home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
DISPOSBL.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
7KB
|
212 lines
/****************************************************************************
$Id: disposbl.cpp 501.0 1995/03/07 12:26:12 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of class TLDisposable.
$Log: disposbl.cpp $
Revision 501.0 1995/03/07 12:26:12 RON
Updated for TLX 5.01
Revision 1.4 1995/01/31 16:30:08 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.3 1995/01/06 15:57:34 ron
Corrected Revision keyword
Revision 1.2 1995/01/05 15:23:34 ron
Renamed tracing macros
Revision 1.1 1994/11/16 15:38:15 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <tlx\501\dispose.h>
/*---------------------------------------------------------------------------
Global and static data
---------------------------------------------------------------------------*/
TLDisposable *TLDisposable::sGarbage = 0; // Chain of garbage objects
/*-------------------------------------------------------------------------*/
TLDisposable::TLDisposable()
/* Constructor. Clears the link field and checks correct initialization.
---------------------------------------------------------------------------*/
{
mNext = 0;
TLX_ASSERT_VALID();
}
/*-------------------------------------------------------------------------*/
TLDisposable::TLDisposable(const TLDisposable &)
/* Copy constructor. Does not copy the link field, but checks correct
initialization.
---------------------------------------------------------------------------*/
{
mNext = 0;
TLX_ASSERT_VALID();
}
/*-------------------------------------------------------------------------*/
TLDisposable::~TLDisposable()
/* Destructor. Ensures that the instance is removed from the garbage list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_VALID();
if (IsMarkedForDisposal()) ExtractFromGarbage();
TLX_ASSERT_NULL(mNext);
}
/*-------------------------------------------------------------------------*/
TLDisposable &TLDisposable::operator =(const TLDisposable &)
/* Assignment operator. Does not copy the link field, but checks the
validity of the object.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_VALID();
return *this;
}
/*-------------------------------------------------------------------------*/
void TLDisposable::AddToGarbage()
/* Adds the object to the garbage list. It is an error to call this
function if the object is already on the garbage list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(!IsMarkedForDisposal());
mNext = sGarbage;
sGarbage = this;
}
/*-------------------------------------------------------------------------*/
void TLDisposable::CollectGarbage()
/* Static function that destroys all objects currently on the garbage
list.
---------------------------------------------------------------------------*/
{
// We rely on the fact that each disposable object will remove itself
// from the list on destruction; because we always remove the head
// object, this is very efficient as well.
while (sGarbage) {
#ifdef _TLXDBG
sGarbage->_mChecker.AssertValid(__FILE__, __LINE__);
#endif
delete sGarbage;
}
}
/*-------------------------------------------------------------------------*/
void TLDisposable::ExtractFromGarbage()
/* Removes the object from the garbage list. It is an error to call this
function if the object is not on the list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(IsMarkedForDisposal());
// It is important that the most common case, i.e. when this instance
// is the first on the list, is handled efficiently.
if (sGarbage == this) {
sGarbage = mNext;
mNext = 0;
} else {
// Search through the list for our predecessor
TLDisposable *pred = sGarbage;
TLX_ASSERT_PTR(pred);
for (TLDisposable *rover = pred->mNext; rover; rover = rover->mNext) {
if (rover == this) {
// Found the object; remove it
pred->mNext = mNext;
mNext = 0;
break;
}
pred = rover;
}
}
TLX_ASSERT(!IsMarkedForDisposal());
}
/*-------------------------------------------------------------------------*/
bool TLDisposable::IsMarkedForDisposal() const
/* Returns true if the object is marked for disposal. This is the case
if the object appears on the garbage list.
---------------------------------------------------------------------------*/
{
#ifdef _TLXDBG
// Traverse the garbage list to see if the object is on it
for (TLDisposable *rover = sGarbage; rover; rover = rover->mNext) {
if (rover == this) {
// Found the object; check invariants
TLX_ASSERT(mNext || sGarbage == this);
return true;
}
}
// Not found on the list
TLX_ASSERT_NULL(mNext);
return false;
#else
// The object is assumed to be on the list if its 'mNext' pointer is
// nonzero and/or if it is the only object on the garbage list.
return mNext || sGarbage == this;
#endif
}
/*-------------------------------------------------------------------------*/
void TLDisposable::MarkForDisposal()
/* Marks the object for disposal by placing it on the garbage list. If
the object was already on the list, the debug version will issue a
warning trace to that effect.
---------------------------------------------------------------------------*/
{
if (IsMarkedForDisposal())
TLX_TRACE_WARN(TLX, ("Object already marked for disposal"));
else
AddToGarbage();
TLX_ASSERT(IsMarkedForDisposal());
}
/*-------------------------------------------------------------------------*/
void TLDisposable::ReclaimObject()
/* Removes the object from the garbage list, assuming it's marked for
disposal and not yet destroyed.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_VALID();
if (IsMarkedForDisposal())
ExtractFromGarbage();
else
TLX_TRACE_WARN(TLX, ("Object not marked for disposal"));
TLX_ASSERT(!IsMarkedForDisposal());
}