root/gc/include/weakpointer.h

/* [<][>][^][v][top][bottom][index][help] */
   1 #ifndef _weakpointer_h_
   2 #define _weakpointer_h_
   3 
   4 /****************************************************************************
   5 
   6 WeakPointer and CleanUp
   7 
   8     Copyright (c) 1991 by Xerox Corporation.  All rights reserved.
   9 
  10     THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  11     OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  12 
  13     Permission is hereby granted to copy this code for any purpose,
  14     provided the above notices are retained on all copies.
  15 
  16     Last modified on Mon Jul 17 18:16:01 PDT 1995 by ellis
  17 
  18 ****************************************************************************/
  19 
  20 /****************************************************************************
  21 
  22 WeakPointer
  23 
  24 A weak pointer is a pointer to a heap-allocated object that doesn't
  25 prevent the object from being garbage collected. Weak pointers can be
  26 used to track which objects haven't yet been reclaimed by the
  27 collector. A weak pointer is deactivated when the collector discovers
  28 its referent object is unreachable by normal pointers (reachability
  29 and deactivation are defined more precisely below). A deactivated weak
  30 pointer remains deactivated forever.
  31 
  32 ****************************************************************************/
  33 
  34 
  35 template< class T > class WeakPointer {
  36 public:
  37 
  38 WeakPointer( T* t = 0 )
  39     /* Constructs a weak pointer for *t. t may be null. It is an error
  40        if t is non-null and *t is not a collected object. */
  41     {impl = _WeakPointer_New( t );}
  42 
  43 T* Pointer()
  44     /* wp.Pointer() returns a pointer to the referent object of wp or
  45        null if wp has been deactivated (because its referent object
  46        has been discovered unreachable by the collector). */
  47     {return (T*) _WeakPointer_Pointer( this->impl );}
  48 
  49 int operator==( WeakPointer< T > wp2 )
  50     /* Given weak pointers wp1 and wp2, if wp1 == wp2, then wp1 and
  51        wp2 refer to the same object. If wp1 != wp2, then either wp1
  52        and wp2 don't refer to the same object, or if they do, one or
  53        both of them has been deactivated. (Note: If objects t1 and t2
  54        are never made reachable by their clean-up functions, then
  55        WeakPointer<T>(t1) == WeakPointer<T>(t2) if and only t1 == t2.) */
  56     {return _WeakPointer_Equal( this->impl, wp2.impl );}
  57 
  58 int Hash()
  59     /* Returns a hash code suitable for use by multiplicative- and
  60        division-based hash tables. If wp1 == wp2, then wp1.Hash() ==
  61        wp2.Hash(). */
  62     {return _WeakPointer_Hash( this->impl );}
  63 
  64 private:
  65 void* impl;
  66 };
  67 
  68 /*****************************************************************************
  69 
  70 CleanUp
  71 
  72 A garbage-collected object can have an associated clean-up function
  73 that will be invoked some time after the collector discovers the
  74 object is unreachable via normal pointers. Clean-up functions can be
  75 used to release resources such as open-file handles or window handles
  76 when their containing objects become unreachable.  If a C++ object has
  77 a non-empty explicit destructor (i.e. it contains programmer-written
  78 code), the destructor will be automatically registered as the object's
  79 initial clean-up function.
  80 
  81 There is no guarantee that the collector will detect every unreachable
  82 object (though it will find almost all of them). Clients should not
  83 rely on clean-up to cause some action to occur immediately -- clean-up
  84 is only a mechanism for improving resource usage.
  85 
  86 Every object with a clean-up function also has a clean-up queue. When
  87 the collector finds the object is unreachable, it enqueues it on its
  88 queue. The clean-up function is applied when the object is removed
  89 from the queue. By default, objects are enqueued on the garbage
  90 collector's queue, and the collector removes all objects from its
  91 queue after each collection. If a client supplies another queue for
  92 objects, it is his responsibility to remove objects (and cause their
  93 functions to be called) by polling it periodically.
  94 
  95 Clean-up queues allow clean-up functions accessing global data to
  96 synchronize with the main program. Garbage collection can occur at any
  97 time, and clean-ups invoked by the collector might access data in an
  98 inconsistent state. A client can control this by defining an explicit
  99 queue for objects and polling it at safe points.
 100 
 101 The following definitions are used by the specification below:
 102 
 103 Given a pointer t to a collected object, the base object BO(t) is the
 104 value returned by new when it created the object. (Because of multiple
 105 inheritance, t and BO(t) may not be the same address.)
 106 
 107 A weak pointer wp references an object *t if BO(wp.Pointer()) ==
 108 BO(t).
 109 
 110 ***************************************************************************/
 111 
 112 template< class T, class Data > class CleanUp {
 113 public:
 114 
 115 static void Set( T* t, void c( Data* d, T* t ), Data* d = 0 )
 116     /* Sets the clean-up function of object BO(t) to be <c, d>,
 117        replacing any previously defined clean-up function for BO(t); c
 118        and d can be null, but t cannot. Sets the clean-up queue for
 119        BO(t) to be the collector's queue. When t is removed from its
 120        clean-up queue, its clean-up will be applied by calling c(d,
 121        t). It is an error if *t is not a collected object. */ 
 122        {_CleanUp_Set( t, c, d );}
 123 
 124 static void Call( T* t )
 125     /* Sets the new clean-up function for BO(t) to be null and, if the
 126        old one is non-null, calls it immediately, even if BO(t) is
 127        still reachable. Deactivates any weak pointers to BO(t). */
 128        {_CleanUp_Call( t );}
 129 
 130 class Queue {public:
 131     Queue()
 132         /* Constructs a new queue. */
 133             {this->head = _CleanUp_Queue_NewHead();}
 134 
 135     void Set( T* t )
 136         /* q.Set(t) sets the clean-up queue of BO(t) to be q. */
 137             {_CleanUp_Queue_Set( this->head, t );}
 138 
 139     int Call()
 140         /* If q is non-empty, q.Call() removes the first object and
 141            calls its clean-up function; does nothing if q is
 142            empty. Returns true if there are more objects in the
 143            queue. */
 144            {return _CleanUp_Queue_Call( this->head );}
 145 
 146     private:
 147     void* head;
 148     };
 149 };
 150 
 151 /**********************************************************************
 152 
 153 Reachability and Clean-up
 154 
 155 An object O is reachable if it can be reached via a non-empty path of
 156 normal pointers from the registers, stacks, global variables, or an
 157 object with a non-null clean-up function (including O itself),
 158 ignoring pointers from an object to itself.
 159 
 160 This definition of reachability ensures that if object B is accessible
 161 from object A (and not vice versa) and if both A and B have clean-up
 162 functions, then A will always be cleaned up before B. Note that as
 163 long as an object with a clean-up function is contained in a cycle of
 164 pointers, it will always be reachable and will never be cleaned up or
 165 collected.
 166 
 167 When the collector finds an unreachable object with a null clean-up
 168 function, it atomically deactivates all weak pointers referencing the
 169 object and recycles its storage. If object B is accessible from object
 170 A via a path of normal pointers, A will be discovered unreachable no
 171 later than B, and a weak pointer to A will be deactivated no later
 172 than a weak pointer to B.
 173 
 174 When the collector finds an unreachable object with a non-null
 175 clean-up function, the collector atomically deactivates all weak
 176 pointers referencing the object, redefines its clean-up function to be
 177 null, and enqueues it on its clean-up queue. The object then becomes
 178 reachable again and remains reachable at least until its clean-up
 179 function executes.
 180 
 181 The clean-up function is assured that its argument is the only
 182 accessible pointer to the object. Nothing prevents the function from
 183 redefining the object's clean-up function or making the object
 184 reachable again (for example, by storing the pointer in a global
 185 variable).
 186 
 187 If the clean-up function does not make its object reachable again and
 188 does not redefine its clean-up function, then the object will be
 189 collected by a subsequent collection (because the object remains
 190 unreachable and now has a null clean-up function). If the clean-up
 191 function does make its object reachable again and a clean-up function
 192 is subsequently redefined for the object, then the new clean-up
 193 function will be invoked the next time the collector finds the object
 194 unreachable.
 195 
 196 Note that a destructor for a collected object cannot safely redefine a
 197 clean-up function for its object, since after the destructor executes,
 198 the object has been destroyed into "raw memory". (In most
 199 implementations, destroying an object mutates its vtbl.)
 200 
 201 Finally, note that calling delete t on a collected object first
 202 deactivates any weak pointers to t and then invokes its clean-up
 203 function (destructor).
 204 
 205 **********************************************************************/
 206 
 207 extern "C" {
 208     void* _WeakPointer_New( void* t );
 209     void* _WeakPointer_Pointer( void* wp );
 210     int _WeakPointer_Equal( void* wp1, void* wp2 );
 211     int _WeakPointer_Hash( void* wp );
 212     void _CleanUp_Set( void* t, void (*c)( void* d, void* t ), void* d );
 213     void _CleanUp_Call( void* t );
 214     void* _CleanUp_Queue_NewHead ();
 215     void _CleanUp_Queue_Set( void* h, void* t );
 216     int _CleanUp_Queue_Call( void* h );
 217 }
 218 
 219 #endif /* _weakpointer_h_ */
 220 
 221 

/* [<][>][^][v][top][bottom][index][help] */