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 hasnt 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       // Dont 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