PageRenderTime 35ms CodeModel.GetById 10ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 1ms

/libs/headers/gc/weakpointer.h

http://github.com/nddrylliog/ooc
C++ Header | 221 lines | 44 code | 22 blank | 155 comment | 0 complexity | 9479459c7cba9ce350f48863b51196c0 MD5 | raw file
  1#ifndef	_weakpointer_h_
  2#define	_weakpointer_h_
  3
  4/****************************************************************************
  5
  6WeakPointer 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
 22WeakPointer
 23
 24A weak pointer is a pointer to a heap-allocated object that doesn't
 25prevent the object from being garbage collected. Weak pointers can be
 26used to track which objects haven't yet been reclaimed by the
 27collector. A weak pointer is deactivated when the collector discovers
 28its referent object is unreachable by normal pointers (reachability
 29and deactivation are defined more precisely below). A deactivated weak
 30pointer remains deactivated forever.
 31
 32****************************************************************************/
 33
 34
 35template< class T > class WeakPointer {
 36public:
 37
 38WeakPointer( 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
 43T* 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
 49int 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
 58int 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
 64private:
 65void* impl;
 66};
 67
 68/*****************************************************************************
 69
 70CleanUp
 71
 72A garbage-collected object can have an associated clean-up function
 73that will be invoked some time after the collector discovers the
 74object is unreachable via normal pointers. Clean-up functions can be
 75used to release resources such as open-file handles or window handles
 76when their containing objects become unreachable.  If a C++ object has
 77a non-empty explicit destructor (i.e. it contains programmer-written
 78code), the destructor will be automatically registered as the object's
 79initial clean-up function.
 80
 81There is no guarantee that the collector will detect every unreachable
 82object (though it will find almost all of them). Clients should not
 83rely on clean-up to cause some action to occur immediately -- clean-up
 84is only a mechanism for improving resource usage.
 85
 86Every object with a clean-up function also has a clean-up queue. When
 87the collector finds the object is unreachable, it enqueues it on its
 88queue. The clean-up function is applied when the object is removed
 89from the queue. By default, objects are enqueued on the garbage
 90collector's queue, and the collector removes all objects from its
 91queue after each collection. If a client supplies another queue for
 92objects, it is his responsibility to remove objects (and cause their
 93functions to be called) by polling it periodically.
 94
 95Clean-up queues allow clean-up functions accessing global data to
 96synchronize with the main program. Garbage collection can occur at any
 97time, and clean-ups invoked by the collector might access data in an
 98inconsistent state. A client can control this by defining an explicit
 99queue for objects and polling it at safe points.
100
101The following definitions are used by the specification below:
102
103Given a pointer t to a collected object, the base object BO(t) is the
104value returned by new when it created the object. (Because of multiple
105inheritance, t and BO(t) may not be the same address.)
106
107A weak pointer wp references an object *t if BO(wp.Pointer()) ==
108BO(t).
109
110***************************************************************************/
111
112template< class T, class Data > class CleanUp {
113public:
114
115static 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
124static 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
130class 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
153Reachability and Clean-up
154
155An object O is reachable if it can be reached via a non-empty path of
156normal pointers from the registers, stacks, global variables, or an
157object with a non-null clean-up function (including O itself),
158ignoring pointers from an object to itself.
159
160This definition of reachability ensures that if object B is accessible
161from object A (and not vice versa) and if both A and B have clean-up
162functions, then A will always be cleaned up before B. Note that as
163long as an object with a clean-up function is contained in a cycle of
164pointers, it will always be reachable and will never be cleaned up or
165collected.
166
167When the collector finds an unreachable object with a null clean-up
168function, it atomically deactivates all weak pointers referencing the
169object and recycles its storage. If object B is accessible from object
170A via a path of normal pointers, A will be discovered unreachable no
171later than B, and a weak pointer to A will be deactivated no later
172than a weak pointer to B.
173
174When the collector finds an unreachable object with a non-null
175clean-up function, the collector atomically deactivates all weak
176pointers referencing the object, redefines its clean-up function to be
177null, and enqueues it on its clean-up queue. The object then becomes
178reachable again and remains reachable at least until its clean-up
179function executes.
180
181The clean-up function is assured that its argument is the only
182accessible pointer to the object. Nothing prevents the function from
183redefining the object's clean-up function or making the object
184reachable again (for example, by storing the pointer in a global
185variable).
186
187If the clean-up function does not make its object reachable again and
188does not redefine its clean-up function, then the object will be
189collected by a subsequent collection (because the object remains
190unreachable and now has a null clean-up function). If the clean-up
191function does make its object reachable again and a clean-up function
192is subsequently redefined for the object, then the new clean-up
193function will be invoked the next time the collector finds the object
194unreachable.
195
196Note that a destructor for a collected object cannot safely redefine a
197clean-up function for its object, since after the destructor executes,
198the object has been destroyed into "raw memory". (In most
199implementations, destroying an object mutates its vtbl.)
200
201Finally, note that calling delete t on a collected object first
202deactivates any weak pointers to t and then invokes its clean-up
203function (destructor).
204
205**********************************************************************/
206
207extern "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