1
2 /**
3 *
4 * Author: Martin Johnson
5 *
6 * Based upon http://www.cs.wustl.edu/~schmidt/PDF/ObjMan.pdf
7 * with some modification.
8 *
9 * Synopsis:
10 * Support for Preallocated Managed Objects and Managed Objects.
11 * Managed Objects are required to grant friendship to the following
12 *
13 * template <class TYPE> friend class ManagedObject;
14 * friend class Object_Lifetime_Manager;
15 *
16 * Applications utilising Object_Lifetime_Manager are required to call
17 *
18 **/
19
20 #ifndef _Object_Lifetime_Manager_
21 #define _Object_Lifetime_Manager_
22
23 #include <util/XmlBCfg.h>
24 #include <string>
25 #include <map>
26 #include <list>
27
28 extern "C"
29 {
30 void object_manager_cleanup();
31 }
32
33 namespace org { namespace xmlBlaster { namespace util {
34
35 class Cleanup_Adaptor
36 {
37 public:
38 Cleanup_Adaptor(){;}
39 virtual ~Cleanup_Adaptor(){;}
40
41 virtual void cleanup(){;}
42 };
43
44 template <class TYPE>
45 class ManagedObject : public Cleanup_Adaptor
46 {
47 public:
48 ManagedObject(TYPE* p):obj_(p) {;}
49 virtual ~ManagedObject(){if(obj_ != 0) delete obj_;}
50
51 virtual void cleanup(){ delete obj_; obj_ = 0;}
52
53 protected:
54 TYPE* obj_;
55
56 private:
57 ManagedObject();
58 ManagedObject(const ManagedObject& in){ obj_ = in.obj_; }
59 };
60
61 typedef std::map<std::string, Cleanup_Adaptor*> ManagedMap;
62 typedef std::list<Cleanup_Adaptor*> ManagedList;
63
64 class Dll_Export Object_Lifetime_Manager_Base
65 {
66 public:
67 // Explicitly initialize. Returns 0 on success,
68 // -1 on failure due to dynamic allocation
69 // failure (in which case errno is set to
70 // ENOMEM), or 1 if it had already been called.
71 virtual int startup (void) = 0;
72
73 // Explicitly destroy. Returns 0 on success,
74 // -1 on failure because the number of <fini>
75 // calls hasn’t reached the number of <init>
76 // calls, or 1 if it had already been called.
77 virtual int shutdown (void) = 0;
78
79 enum Object_Lifetime_Manager_State
80 {
81 OBJ_MAN_UNINITIALIZED,
82 OBJ_MAN_INITIALIZING,
83 OBJ_MAN_INITIALIZED,
84 OBJ_MAN_SHUTTING_DOWN,
85 OBJ_MAN_SHUT_DOWN
86 };
87
88 protected:
89
90 Object_Lifetime_Manager_Base (void) :
91 object_manager_state_ (OBJ_MAN_UNINITIALIZED),
92 dynamically_allocated_ (0) {}
93
94 virtual ~Object_Lifetime_Manager_Base (void)
95 {
96 // Clear the flag so that fini
97 // does not delete again.
98 dynamically_allocated_ = 0;
99 }
100
101 /**
102 * This flag can be used to determine if the program is constructing
103 * static objects.
104 * If no static object spawns any threads, the program will be
105 * single-threaded when this flag returns 1.
106 * @return 1 before Object_Lifetime_Manager_Base
107 * has been constructed.
108 */
109 int starting_up_i (void)
110 {
111 return object_manager_state_ < OBJ_MAN_INITIALIZED;
112 }
113
114 /**
115 * @return 1 after Object_Lifetime_Manager_Base
116 * has been destroyed.
117 */
118 int shutting_down_i (void)
119 {
120 return object_manager_state_ > OBJ_MAN_INITIALIZED;
121 }
122
123 /** State of the Object_Lifetime_Manager; */
124 Object_Lifetime_Manager_State object_manager_state_;
125
126 /**
127 * Flag indicating whether the
128 * Object_Lifetime_Manager instance was
129 * dynamically allocated by the library.
130 * (If it was dynamically allocated by the
131 * application, then the application is
132 * responsible for deleting it.)
133 */
134 int dynamically_allocated_;
135
136 };
137
138 class Dll_Export Object_Lifetime_Manager : public Object_Lifetime_Manager_Base
139 {
140 public:
141
142 static void init (void);
143 static void fini (void);
144
145 virtual int startup (void);
146 virtual int shutdown (void);
147
148 static int starting_up (void)
149 {
150 return instance_ ? instance_->starting_up_i () : 1;
151 }
152
153 static int shutting_down (void)
154 {
155 return instance_ ? instance_->shutting_down_i () : 1;
156 }
157
158 /**
159 * Unique identifiers for Preallocated Objects.
160 */
161 enum Preallocated_Object
162 {
163 XMLBLASTER_GLOBAL,
164 PREALLOCATED_OBJECTS
165 };
166
167 /**
168 * Accessor to singleton instance.
169 *
170 * This function should be called during
171 * construction of static instances, or
172 * before any other threads have been created
173 * in the process. So, it’s not thread safe.
174 */
175 static Object_Lifetime_Manager *instance (void);
176 public:
177
178 Object_Lifetime_Manager (void)
179 {
180 // Make sure that no further instances are
181 // created via instance.
182 if (instance_ == 0) {
183 instance_ = this;
184
185 // shown to be useless though if some one else has a better
186 // opinion. Doesnt work in win32 land.
187 //atexit(object_manager_cleanup);
188 }
189 init ();
190 }
191
192 ~Object_Lifetime_Manager (void)
193 {
194 // Don’t delete this again in fini.
195 dynamically_allocated_ = 0;
196 fini ();
197 }
198
199 /**
200 * Add a new object to be managed on startup/shutdown.
201 * <p />
202 * If you want to lookup the managed object at any time you
203 * should use the
204 * <code>manage_object(const std::string& key, T* obj)</code>
205 * variant.
206 * @param obj The instance to lifecycle-manage
207 */
208 template <class T> void manage_object(T* obj)
209 {
210 ManagedObject<T>* mobj = new ManagedObject<T>(obj);
211 managedObjectList_.push_back(mobj);
212 }
213
214 /**
215 * Add a new object to be managed on startup/shutdown
216 *
217 * @param key The unique key of this object, you can lookup this instance later if desired
218 * @param obj The instance to lifecycle-manage
219 */
220 template <class T> void manage_object(const std::string& key, T* obj)
221 {
222 ManagedObject<T>* mobj = new ManagedObject<T>(obj);
223 managedObjectList_.push_back(mobj);
224 managedObjectMap_[key] = mobj;
225 }
226
227 /**
228 * Lookup a managed object by its registration key
229 * @return Pointer on managed object or NULL if not found
230 */
231 template <class T> T* getManagedObject(const std::string& key)
232 {
233 ManagedMap::iterator mi = managedObjectMap_.find(key);
234 if (mi != managedObjectMap_.end()) {
235 return (*mi).second;
236 }
237 return (T *)0;
238 }
239
240 private:
241
242 /** Singleton instance pointer. */
243 static Object_Lifetime_Manager *instance_;
244
245 /** Array of Preallocated Objects. */
246 static void * preallocated_object[PREALLOCATED_OBJECTS];
247
248 static ManagedMap managedObjectMap_;
249 static ManagedList managedObjectList_;
250 };
251
252 }}} //namespace
253
254 #endif
syntax highlighted by Code2HTML, v. 0.9.1