00001 00020 #ifndef _Object_Lifetime_Manager_ 00021 #define _Object_Lifetime_Manager_ 00022 00023 #include <util/XmlBCfg.h> 00024 #include <string> 00025 #include <map> 00026 #include <list> 00027 00028 extern "C" 00029 { 00030 void object_manager_cleanup(); 00031 } 00032 00033 namespace org { namespace xmlBlaster { namespace util { 00034 00035 class Cleanup_Adaptor 00036 { 00037 public: 00038 Cleanup_Adaptor(){;} 00039 virtual ~Cleanup_Adaptor(){;} 00040 00041 virtual void cleanup(){;} 00042 }; 00043 00044 template <class TYPE> 00045 class ManagedObject : public Cleanup_Adaptor 00046 { 00047 public: 00048 ManagedObject(TYPE* p):obj_(p) {;} 00049 virtual ~ManagedObject(){if(obj_ != 0) delete obj_;} 00050 00051 virtual void cleanup(){ delete obj_; obj_ = 0;} 00052 00053 protected: 00054 TYPE* obj_; 00055 00056 private: 00057 ManagedObject(); 00058 ManagedObject(const ManagedObject& in){ obj_ = in.obj_; } 00059 }; 00060 00061 typedef std::map<std::string, Cleanup_Adaptor*> ManagedMap; 00062 typedef std::list<Cleanup_Adaptor*> ManagedList; 00063 00064 class Dll_Export Object_Lifetime_Manager_Base 00065 { 00066 public: 00067 // Explicitly initialize. Returns 0 on success, 00068 // -1 on failure due to dynamic allocation 00069 // failure (in which case errno is set to 00070 // ENOMEM), or 1 if it had already been called. 00071 virtual int startup (void) = 0; 00072 00073 // Explicitly destroy. Returns 0 on success, 00074 // -1 on failure because the number of <fini> 00075 // calls hasn’t reached the number of <init> 00076 // calls, or 1 if it had already been called. 00077 virtual int shutdown (void) = 0; 00078 00079 enum Object_Lifetime_Manager_State 00080 { 00081 OBJ_MAN_UNINITIALIZED, 00082 OBJ_MAN_INITIALIZING, 00083 OBJ_MAN_INITIALIZED, 00084 OBJ_MAN_SHUTTING_DOWN, 00085 OBJ_MAN_SHUT_DOWN 00086 }; 00087 00088 protected: 00089 00090 Object_Lifetime_Manager_Base (void) : 00091 object_manager_state_ (OBJ_MAN_UNINITIALIZED), 00092 dynamically_allocated_ (0) {} 00093 00094 virtual ~Object_Lifetime_Manager_Base (void) 00095 { 00096 // Clear the flag so that fini 00097 // does not delete again. 00098 dynamically_allocated_ = 0; 00099 } 00100 00109 int starting_up_i (void) 00110 { 00111 return object_manager_state_ < OBJ_MAN_INITIALIZED; 00112 } 00113 00118 int shutting_down_i (void) 00119 { 00120 return object_manager_state_ > OBJ_MAN_INITIALIZED; 00121 } 00122 00124 Object_Lifetime_Manager_State object_manager_state_; 00125 00134 int dynamically_allocated_; 00135 00136 }; 00137 00138 class Dll_Export Object_Lifetime_Manager : public Object_Lifetime_Manager_Base 00139 { 00140 public: 00141 00142 static void init (void); 00143 static void fini (void); 00144 00145 virtual int startup (void); 00146 virtual int shutdown (void); 00147 00148 static int starting_up (void) 00149 { 00150 return instance_ ? instance_->starting_up_i () : 1; 00151 } 00152 00153 static int shutting_down (void) 00154 { 00155 return instance_ ? instance_->shutting_down_i () : 1; 00156 } 00157 00161 enum Preallocated_Object 00162 { 00163 XMLBLASTER_GLOBAL, 00164 PREALLOCATED_OBJECTS 00165 }; 00166 00175 static Object_Lifetime_Manager *instance (void); 00176 public: 00177 00178 Object_Lifetime_Manager (void) 00179 { 00180 // Make sure that no further instances are 00181 // created via instance. 00182 if (instance_ == 0) { 00183 instance_ = this; 00184 00185 // shown to be useless though if some one else has a better 00186 // opinion. Doesnt work in win32 land. 00187 //atexit(object_manager_cleanup); 00188 } 00189 init (); 00190 } 00191 00192 ~Object_Lifetime_Manager (void) 00193 { 00194 // Don’t delete this again in fini. 00195 dynamically_allocated_ = 0; 00196 fini (); 00197 } 00198 00208 template <class T> void manage_object(T* obj) 00209 { 00210 ManagedObject<T>* mobj = new ManagedObject<T>(obj); 00211 managedObjectList_.push_back(mobj); 00212 } 00213 00220 template <class T> void manage_object(const std::string& key, T* obj) 00221 { 00222 ManagedObject<T>* mobj = new ManagedObject<T>(obj); 00223 managedObjectList_.push_back(mobj); 00224 managedObjectMap_[key] = mobj; 00225 } 00226 00231 template <class T> T* getManagedObject(const std::string& key) 00232 { 00233 ManagedMap::iterator mi = managedObjectMap_.find(key); 00234 if (mi != managedObjectMap_.end()) { 00235 return (*mi).second; 00236 } 00237 return (T *)0; 00238 } 00239 00240 private: 00241 00243 static Object_Lifetime_Manager *instance_; 00244 00246 static void * preallocated_object[PREALLOCATED_OBJECTS]; 00247 00248 static ManagedMap managedObjectMap_; 00249 static ManagedList managedObjectList_; 00250 }; 00251 00252 }}} //namespace 00253 00254 #endif 00255 00256