Annotation of OpenXM_contrib2/asir2000/gc/include/weakpointer.h, Revision 1.1
1.1 ! noro 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>