util/objman.h

Go to the documentation of this file.
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