Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
weakpointer.h
00001 #ifndef _weakpointer_h_ 00002 #define _weakpointer_h_ 00003 00004 /**************************************************************************** 00005 00006 WeakPointer and CleanUp 00007 00008 Copyright (c) 1991 by Xerox Corporation. All rights reserved. 00009 00010 THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 00011 OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 00012 00013 Permission is hereby granted to copy this code for any purpose, 00014 provided the above notices are retained on all copies. 00015 00016 Last modified on Mon Jul 17 18:16:01 PDT 1995 by ellis 00017 00018 ****************************************************************************/ 00019 00020 /**************************************************************************** 00021 00022 WeakPointer 00023 00024 A weak pointer is a pointer to a heap-allocated object that doesn't 00025 prevent the object from being garbage collected. Weak pointers can be 00026 used to track which objects haven't yet been reclaimed by the 00027 collector. A weak pointer is deactivated when the collector discovers 00028 its referent object is unreachable by normal pointers (reachability 00029 and deactivation are defined more precisely below). A deactivated weak 00030 pointer remains deactivated forever. 00031 00032 ****************************************************************************/ 00033 00034 00035 template< class T > class WeakPointer { 00036 public: 00037 00038 WeakPointer( T* t = 0 ) 00039 /* Constructs a weak pointer for *t. t may be null. It is an error 00040 if t is non-null and *t is not a collected object. */ 00041 {impl = _WeakPointer_New( t );} 00042 00043 T* Pointer() 00044 /* wp.Pointer() returns a pointer to the referent object of wp or 00045 null if wp has been deactivated (because its referent object 00046 has been discovered unreachable by the collector). */ 00047 {return (T*) _WeakPointer_Pointer( this->impl );} 00048 00049 int operator==( WeakPointer< T > wp2 ) 00050 /* Given weak pointers wp1 and wp2, if wp1 == wp2, then wp1 and 00051 wp2 refer to the same object. If wp1 != wp2, then either wp1 00052 and wp2 don't refer to the same object, or if they do, one or 00053 both of them has been deactivated. (Note: If objects t1 and t2 00054 are never made reachable by their clean-up functions, then 00055 WeakPointer<T>(t1) == WeakPointer<T>(t2) if and only t1 == t2.) */ 00056 {return _WeakPointer_Equal( this->impl, wp2.impl );} 00057 00058 int Hash() 00059 /* Returns a hash code suitable for use by multiplicative- and 00060 division-based hash tables. If wp1 == wp2, then wp1.Hash() == 00061 wp2.Hash(). */ 00062 {return _WeakPointer_Hash( this->impl );} 00063 00064 private: 00065 void* impl; 00066 }; 00067 00068 /***************************************************************************** 00069 00070 CleanUp 00071 00072 A garbage-collected object can have an associated clean-up function 00073 that will be invoked some time after the collector discovers the 00074 object is unreachable via normal pointers. Clean-up functions can be 00075 used to release resources such as open-file handles or window handles 00076 when their containing objects become unreachable. If a C++ object has 00077 a non-empty explicit destructor (i.e. it contains programmer-written 00078 code), the destructor will be automatically registered as the object's 00079 initial clean-up function. 00080 00081 There is no guarantee that the collector will detect every unreachable 00082 object (though it will find almost all of them). Clients should not 00083 rely on clean-up to cause some action to occur immediately -- clean-up 00084 is only a mechanism for improving resource usage. 00085 00086 Every object with a clean-up function also has a clean-up queue. When 00087 the collector finds the object is unreachable, it enqueues it on its 00088 queue. The clean-up function is applied when the object is removed 00089 from the queue. By default, objects are enqueued on the garbage 00090 collector's queue, and the collector removes all objects from its 00091 queue after each collection. If a client supplies another queue for 00092 objects, it is his responsibility to remove objects (and cause their 00093 functions to be called) by polling it periodically. 00094 00095 Clean-up queues allow clean-up functions accessing global data to 00096 synchronize with the main program. Garbage collection can occur at any 00097 time, and clean-ups invoked by the collector might access data in an 00098 inconsistent state. A client can control this by defining an explicit 00099 queue for objects and polling it at safe points. 00100 00101 The following definitions are used by the specification below: 00102 00103 Given a pointer t to a collected object, the base object BO(t) is the 00104 value returned by new when it created the object. (Because of multiple 00105 inheritance, t and BO(t) may not be the same address.) 00106 00107 A weak pointer wp references an object *t if BO(wp.Pointer()) == 00108 BO(t). 00109 00110 ***************************************************************************/ 00111 00112 template< class T, class Data > class CleanUp { 00113 public: 00114 00115 static void Set( T* t, void c( Data* d, T* t ), Data* d = 0 ) 00116 /* Sets the clean-up function of object BO(t) to be <c, d>, 00117 replacing any previously defined clean-up function for BO(t); c 00118 and d can be null, but t cannot. Sets the clean-up queue for 00119 BO(t) to be the collector's queue. When t is removed from its 00120 clean-up queue, its clean-up will be applied by calling c(d, 00121 t). It is an error if *t is not a collected object. */ 00122 {_CleanUp_Set( t, c, d );} 00123 00124 static void Call( T* t ) 00125 /* Sets the new clean-up function for BO(t) to be null and, if the 00126 old one is non-null, calls it immediately, even if BO(t) is 00127 still reachable. Deactivates any weak pointers to BO(t). */ 00128 {_CleanUp_Call( t );} 00129 00130 class Queue {public: 00131 Queue() 00132 /* Constructs a new queue. */ 00133 {this->head = _CleanUp_Queue_NewHead();} 00134 00135 void Set( T* t ) 00136 /* q.Set(t) sets the clean-up queue of BO(t) to be q. */ 00137 {_CleanUp_Queue_Set( this->head, t );} 00138 00139 int Call() 00140 /* If q is non-empty, q.Call() removes the first object and 00141 calls its clean-up function; does nothing if q is 00142 empty. Returns true if there are more objects in the 00143 queue. */ 00144 {return _CleanUp_Queue_Call( this->head );} 00145 00146 private: 00147 void* head; 00148 }; 00149 }; 00150 00151 /********************************************************************** 00152 00153 Reachability and Clean-up 00154 00155 An object O is reachable if it can be reached via a non-empty path of 00156 normal pointers from the registers, stacks, global variables, or an 00157 object with a non-null clean-up function (including O itself), 00158 ignoring pointers from an object to itself. 00159 00160 This definition of reachability ensures that if object B is accessible 00161 from object A (and not vice versa) and if both A and B have clean-up 00162 functions, then A will always be cleaned up before B. Note that as 00163 long as an object with a clean-up function is contained in a cycle of 00164 pointers, it will always be reachable and will never be cleaned up or 00165 collected. 00166 00167 When the collector finds an unreachable object with a null clean-up 00168 function, it atomically deactivates all weak pointers referencing the 00169 object and recycles its storage. If object B is accessible from object 00170 A via a path of normal pointers, A will be discovered unreachable no 00171 later than B, and a weak pointer to A will be deactivated no later 00172 than a weak pointer to B. 00173 00174 When the collector finds an unreachable object with a non-null 00175 clean-up function, the collector atomically deactivates all weak 00176 pointers referencing the object, redefines its clean-up function to be 00177 null, and enqueues it on its clean-up queue. The object then becomes 00178 reachable again and remains reachable at least until its clean-up 00179 function executes. 00180 00181 The clean-up function is assured that its argument is the only 00182 accessible pointer to the object. Nothing prevents the function from 00183 redefining the object's clean-up function or making the object 00184 reachable again (for example, by storing the pointer in a global 00185 variable). 00186 00187 If the clean-up function does not make its object reachable again and 00188 does not redefine its clean-up function, then the object will be 00189 collected by a subsequent collection (because the object remains 00190 unreachable and now has a null clean-up function). If the clean-up 00191 function does make its object reachable again and a clean-up function 00192 is subsequently redefined for the object, then the new clean-up 00193 function will be invoked the next time the collector finds the object 00194 unreachable. 00195 00196 Note that a destructor for a collected object cannot safely redefine a 00197 clean-up function for its object, since after the destructor executes, 00198 the object has been destroyed into "raw memory". (In most 00199 implementations, destroying an object mutates its vtbl.) 00200 00201 Finally, note that calling delete t on a collected object first 00202 deactivates any weak pointers to t and then invokes its clean-up 00203 function (destructor). 00204 00205 **********************************************************************/ 00206 00207 extern "C" { 00208 void* _WeakPointer_New( void* t ); 00209 void* _WeakPointer_Pointer( void* wp ); 00210 int _WeakPointer_Equal( void* wp1, void* wp2 ); 00211 int _WeakPointer_Hash( void* wp ); 00212 void _CleanUp_Set( void* t, void (*c)( void* d, void* t ), void* d ); 00213 void _CleanUp_Call( void* t ); 00214 void* _CleanUp_Queue_NewHead (); 00215 void _CleanUp_Queue_Set( void* h, void* t ); 00216 int _CleanUp_Queue_Call( void* h ); 00217 } 00218 00219 #endif /* _weakpointer_h_ */ 00220 00221
Generated on Tue Jul 12 2022 19:59:55 by
1.7.2