annotate gc/include/weakpointer.h @ 51488:5de98dce4bd1

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