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