home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / DISPOSBL.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  7KB  |  212 lines

  1. /****************************************************************************
  2.     $Id: disposbl.cpp 501.0 1995/03/07 12:26:12 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of class TLDisposable.
  10.  
  11.     $Log: disposbl.cpp $
  12.     Revision 501.0  1995/03/07 12:26:12  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.4  1995/01/31 16:30:08  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.3  1995/01/06  15:57:34    ron
  18.     Corrected Revision keyword
  19.  
  20.     Revision 1.2  1995/01/05  15:23:34    ron
  21.     Renamed tracing macros
  22.  
  23.     Revision 1.1  1994/11/16  15:38:15    ron
  24.     Initial revision
  25.  
  26. ****************************************************************************/
  27.  
  28. #include <tlx\501\_build.h>
  29.  
  30. TLX_MODULE_INFO("$Revision: 501.0 $");
  31.  
  32. #include <tlx\501\dispose.h>
  33.  
  34. /*---------------------------------------------------------------------------
  35.     Global and static data
  36. ---------------------------------------------------------------------------*/
  37.  
  38. TLDisposable *TLDisposable::sGarbage = 0;   // Chain of garbage objects
  39.  
  40. /*-------------------------------------------------------------------------*/
  41.     TLDisposable::TLDisposable()
  42.  
  43. /*  Constructor. Clears the link field and checks correct initialization.
  44. ---------------------------------------------------------------------------*/
  45. {
  46.     mNext = 0;
  47.     TLX_ASSERT_VALID();
  48. }
  49.  
  50. /*-------------------------------------------------------------------------*/
  51.     TLDisposable::TLDisposable(const TLDisposable &)
  52.  
  53. /*  Copy constructor. Does not copy the link field, but checks correct
  54.     initialization.
  55. ---------------------------------------------------------------------------*/
  56. {
  57.     mNext = 0;
  58.     TLX_ASSERT_VALID();
  59. }
  60.  
  61. /*-------------------------------------------------------------------------*/
  62.     TLDisposable::~TLDisposable()
  63.  
  64. /*  Destructor. Ensures that the instance is removed from the garbage list.
  65. ---------------------------------------------------------------------------*/
  66. {
  67.     TLX_ASSERT_VALID();
  68.     if (IsMarkedForDisposal()) ExtractFromGarbage();
  69.     TLX_ASSERT_NULL(mNext);
  70. }
  71.  
  72. /*-------------------------------------------------------------------------*/
  73.     TLDisposable &TLDisposable::operator =(const TLDisposable &)
  74.  
  75. /*  Assignment operator. Does not copy the link field, but checks the
  76.     validity of the object.
  77. ---------------------------------------------------------------------------*/
  78. {
  79.     TLX_ASSERT_VALID();
  80.     return *this;
  81. }
  82.  
  83. /*-------------------------------------------------------------------------*/
  84.     void TLDisposable::AddToGarbage()
  85.  
  86. /*  Adds the object to the garbage list. It is an error to call this
  87.     function if the object is already on the garbage list.
  88. ---------------------------------------------------------------------------*/
  89. {
  90.     TLX_ASSERT(!IsMarkedForDisposal());
  91.     mNext = sGarbage;
  92.     sGarbage = this;
  93. }
  94.  
  95. /*-------------------------------------------------------------------------*/
  96.     void TLDisposable::CollectGarbage()
  97.  
  98. /*  Static function that destroys all objects currently on the garbage
  99.     list.
  100. ---------------------------------------------------------------------------*/
  101. {
  102.     // We rely on the fact that each disposable object will remove itself
  103.     // from the list on destruction; because we always remove the head
  104.     // object, this is very efficient as well.
  105.  
  106.     while (sGarbage) {
  107.       #ifdef _TLXDBG
  108.     sGarbage->_mChecker.AssertValid(__FILE__, __LINE__);
  109.       #endif
  110.     delete sGarbage;
  111.     }
  112. }
  113.  
  114. /*-------------------------------------------------------------------------*/
  115.     void TLDisposable::ExtractFromGarbage()
  116.  
  117. /*  Removes the object from the garbage list. It is an error to call this
  118.     function if the object is not on the list.
  119. ---------------------------------------------------------------------------*/
  120. {
  121.     TLX_ASSERT(IsMarkedForDisposal());
  122.  
  123.     // It is important that the most common case, i.e. when this instance
  124.     // is the first on the list, is handled efficiently.
  125.  
  126.     if (sGarbage == this) {
  127.     sGarbage = mNext;
  128.     mNext = 0;
  129.     } else {
  130.     // Search through the list for our predecessor
  131.  
  132.     TLDisposable *pred = sGarbage;
  133.     TLX_ASSERT_PTR(pred);
  134.  
  135.     for (TLDisposable *rover = pred->mNext; rover; rover = rover->mNext) {
  136.         if (rover == this) {
  137.         // Found the object; remove it
  138.  
  139.         pred->mNext = mNext;
  140.         mNext = 0;
  141.         break;
  142.         }
  143.         pred = rover;
  144.     }
  145.     }
  146.     TLX_ASSERT(!IsMarkedForDisposal());
  147. }
  148.  
  149. /*-------------------------------------------------------------------------*/
  150.     bool TLDisposable::IsMarkedForDisposal() const
  151.  
  152. /*  Returns true if the object is marked for disposal. This is the case
  153.     if the object appears on the garbage list.
  154. ---------------------------------------------------------------------------*/
  155. {
  156. #ifdef _TLXDBG
  157.     // Traverse the garbage list to see if the object is on it
  158.  
  159.     for (TLDisposable *rover = sGarbage; rover; rover = rover->mNext) {
  160.     if (rover == this) {
  161.         // Found the object; check invariants
  162.  
  163.         TLX_ASSERT(mNext || sGarbage == this);
  164.         return true;
  165.     }
  166.     }
  167.  
  168.     // Not found on the list
  169.  
  170.     TLX_ASSERT_NULL(mNext);
  171.     return false;
  172. #else
  173.     // The object is assumed to be on the list if its 'mNext' pointer is
  174.     // nonzero and/or if it is the only object on the garbage list.
  175.  
  176.     return mNext || sGarbage == this;
  177. #endif
  178. }
  179.  
  180. /*-------------------------------------------------------------------------*/
  181.     void TLDisposable::MarkForDisposal()
  182.  
  183. /*  Marks the object for disposal by placing it on the garbage list. If
  184.     the object was already on the list, the debug version will issue a
  185.     warning trace to that effect.
  186. ---------------------------------------------------------------------------*/
  187. {
  188.     if (IsMarkedForDisposal())
  189.     TLX_TRACE_WARN(TLX, ("Object already marked for disposal"));
  190.     else
  191.     AddToGarbage();
  192.  
  193.     TLX_ASSERT(IsMarkedForDisposal());
  194. }
  195.  
  196. /*-------------------------------------------------------------------------*/
  197.     void TLDisposable::ReclaimObject()
  198.  
  199. /*  Removes the object from the garbage list, assuming it's marked for
  200.     disposal and not yet destroyed.
  201. ---------------------------------------------------------------------------*/
  202. {
  203.     TLX_ASSERT_VALID();
  204.     if (IsMarkedForDisposal())
  205.     ExtractFromGarbage();
  206.     else
  207.     TLX_TRACE_WARN(TLX, ("Object not marked for disposal"));
  208.  
  209.     TLX_ASSERT(!IsMarkedForDisposal());
  210. }
  211.  
  212.