fix a bunch of mork memory leaks r=naving, sr=sspitzer 99111 21114 and others

This commit is contained in:
bienvenu%netscape.com 2001-10-06 01:16:24 +00:00
parent eff1e38d5e
commit b1c5a18204
9 changed files with 60 additions and 6 deletions

View File

@ -109,6 +109,7 @@ morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_OwnsHeap ( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
MORK_ASSERT(ioSlotHeap && ioFactory );
@ -149,6 +150,7 @@ morkEnv::morkEnv(morkEnv* ev, /*i*/
, mEnv_DoTrace( morkBool_kFalse )
, mEnv_AutoClear( morkAble_kDisabled )
, mEnv_ShouldAbort( morkBool_kFalse )
, mEnv_OwnsHeap ( morkBool_kFalse )
, mEnv_BeVerbose( morkEnv_kBeVerbose )
{
// $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv??
@ -185,8 +187,11 @@ morkEnv::CloseEnv(morkEnv* ev) /*i*/ // called by CloseMorkNode();
mEnv_SelfAsMdbEnv = 0;
mEnv_ErrorHook = 0;
morkPool* savePool = mEnv_HandlePool;
morkPool::SlotStrongPool((morkPool*) 0, ev, &mEnv_HandlePool);
// free the pool
if (savePool && mEnv_Heap)
mEnv_Heap->Free(this->AsMdbEnv(), savePool);
// mEnv_Factory is NOT refcounted
this->MarkShut();

View File

@ -119,6 +119,7 @@ public: // state is public because the entire Mork system is private
mork_able mEnv_AutoClear;
mork_bool mEnv_ShouldAbort;
mork_bool mEnv_BeVerbose;
mork_bool mEnv_OwnsHeap;
// { ===== begin morkNode interface =====
public: // morkNode virtual methods

View File

@ -417,6 +417,10 @@ morkHandle::Handle_CutStrongRef(nsIMdbEnv* mev)
morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
// called at strong refs zero
{
// if only one ref, Handle_CutStrongRef will clean up better.
if (mNode_Uses == 1)
return Handle_CutStrongRef(mev);
mdb_err outErr = 0;
if ( this->IsNode() && this->IsOpenNode() )

View File

@ -215,7 +215,10 @@ morkNode::ZapOld(morkEnv* ev, nsIMdbHeap* ioHeap)
{
if ( h->mHandle_Face )
{
ev->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face);
if (ev->mEnv_HandlePool)
ev->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face);
else if (h->mHandle_Env && h->mHandle_Env->mEnv_HandlePool)
h->mHandle_Env->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face);
}
else
ev->NilPointerError();

View File

@ -158,6 +158,11 @@ morkPool::ClosePool(morkEnv* ev) // called by CloseMorkNode();
while ( (aLink = d->RemoveFirst()) != 0 )
heap->Free(mev, aLink);
// if the pool's closed, get rid of the frames in use too.
d = &mPool_UsedHandleFrames;
while ( (aLink = d->RemoveFirst()) != 0 )
heap->Free(mev, aLink);
this->MarkShut();
}
else
@ -212,6 +217,12 @@ morkPool::ZapHandle(morkEnv* ev, morkHandleFace* ioHandle)
morkLink* handleLink = (morkLink*) ioHandle;
mPool_FreeHandleFrames.AddLast(handleLink);
++mPool_FreeFramesCount;
// lets free all handles to track down leaks
// - uncomment out next 3 lines, comment out above 2
// nsIMdbHeap* heap = mPool_Heap;
// nsIMdbEnv* mev = ev->AsMdbEnv();
// heap->Free(mev, handleLink);
}
}

View File

@ -269,8 +269,7 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
{
nsIMdbFile* file = mStore_File;
if ( file )
file->CloseMdbObject(ev->AsMdbEnv());
mork_refs refCnt = file->AddStrongRef(ev->AsMdbEnv());
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
&mStore_OidAtomSpace);
@ -285,6 +284,10 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev,
&mStore_File);
refCnt = file->CutStrongRef(ev->AsMdbEnv());
if ( refCnt > 0 )
file->CloseMdbObject(ev->AsMdbEnv());
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_OutStream);

View File

@ -67,6 +67,19 @@ orkinEnv:: ~orkinEnv() // morkHandle destructor does everything
{
}
void orkinEnv::CloseMorkNode(morkEnv* ev) // override to clean up mork env
{
morkEnv* mev = (morkEnv*) this->mHandle_Object;
if ( mev->IsOpenNode() )
{
mev->MarkClosing();
mev->CloseEnv(ev);
mev->MarkShut();
}
morkHandle::CloseMorkNode(ev);
}
/*protected non-poly construction*/
orkinEnv::orkinEnv(morkEnv* ev, // morkUsage is morkUsage_kPool
morkHandleFace* ioFace, // must not be nil, cookie for this handle
@ -212,7 +225,19 @@ orkinEnv::CutStrongRef(nsIMdbEnv* mev)
/*virtual*/ mdb_err
orkinEnv::CloseMdbObject(nsIMdbEnv* mev)
{
return this->Handle_CloseMdbObject(mev);
morkEnv* ev = (morkEnv*) this->mHandle_Object;
mdb_err ret = this->Handle_CloseMdbObject(mev);
if (ev && ev->mEnv_Heap)
{
mork_bool ownsHeap = ev->mEnv_OwnsHeap;
nsIMdbHeap*saveHeap = ev->mEnv_Heap;
ev->mEnv_Heap->Free(this, ev);
if (ownsHeap)
delete saveHeap;
}
return ret;
}
/*virtual*/ mdb_err

View File

@ -69,7 +69,7 @@ class orkinEnv : public morkHandle, public nsIMdbEnv { // nsIMdbObject
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
// virtual void CloseMorkNode(morkEnv* ev); // morkHandle is fine
virtual void CloseMorkNode(morkEnv* ev); // override to clean up mork env
virtual ~orkinEnv(); // morkHandle destructor does everything
protected: // construction is protected (use the static Make() method)

View File

@ -383,6 +383,7 @@ orkinFactory::MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv)
{
mdb_err outErr = 0;
nsIMdbEnv* outEnv = 0;
mork_bool ownsHeap = (ioHeap == 0);
if ( !ioHeap )
ioHeap = new orkinHeap();
@ -397,6 +398,7 @@ orkinFactory::MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv)
if ( newEnv )
{
newEnv->mEnv_OwnsHeap = ownsHeap;
newEnv->mNode_Refs += morkEnv_kWeakRefCountEnvBonus;
orkinEnv* oenv = orkinEnv::MakeEnv(fenv, newEnv);