Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Object_Manager.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Object_Manager.h
00006  *
00007  *  $Id: Object_Manager.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00008  *
00009  *  @author David L. Levine <levine@cs.wustl.edu>
00010  *  @author Matthias Kerkhoff
00011  *  @author and Per Andersson
00012  */
00013 //=============================================================================
00014 
00015 #ifndef ACE_OBJECT_MANAGER_H
00016 #define ACE_OBJECT_MANAGER_H
00017 #include "ace/pre.h"
00018 
00019 #include "ace/OS.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 // Forward declarations.
00026 class ACE_Object_Manager_Preallocations;
00027 class ACE_Sig_Adapter;
00028 class ACE_Sig_Set;
00029 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00030   class ACE_Mutex;
00031   class ACE_Null_Mutex;
00032   class ACE_Thread_Mutex;
00033   class ACE_Recursive_Thread_Mutex;
00034   class ACE_RW_Thread_Mutex;
00035 #endif /* ACE_MT_SAFE */
00036 
00037 class ACE_Cleanup_Info_Node;
00038 template <class T> class ACE_Cleanup_Adapter;
00039 
00040 
00041 // Configuration parameters.
00042 #if !defined (ACE_MAX_MANAGED_OBJECTS)
00043 # define ACE_MAX_MANAGED_OBJECTS 128
00044 #endif /* ! ACE_MAX_MANAGED_OBJECTS */
00045 
00046 #if !defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS)
00047 # define ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS
00048 #endif /* ! ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS */
00049 
00050 #if !defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS)
00051 # define ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS
00052 #endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */
00053 
00054 
00055 /**
00056  * @class ACE_Object_Manager
00057  *
00058  * @brief Manager for ACE library services and singleton cleanup.
00059  *
00060  * The <ACE_Object_Manager> manages cleanup of objects, typically
00061  * singletons, at program termination.  In addition to managing
00062  * the cleanup of the ACE library, it provides an interface for
00063  * application to register objects to be cleaned up.
00064  * This class also shuts down ACE library services, so that they
00065  * can reclaim their storage, at program termination.  It works
00066  * by creating a static instance whose destructor gets called
00067  * along with those of all other static objects.  Hooks are
00068  * provided for application code to register objects and arrays
00069  * for cleanup, e.g., destruction.  The order of such cleanup
00070  * calls is in the reverse order of registration, i.e., that
00071  * last object/array to register gets cleaned up first.
00072  * The <ACE_Object_Manager> API includes <ACE_Managed_Object>.  That
00073  * class is contained in a separate file because it is a
00074  * template class, and some compilers require that template and
00075  * non-template class definitions appear in separate files.
00076  * Please see ace/Managed_Object.h for a description of that
00077  * part of the API.  In summary, <ACE_Managed_Object> provides two
00078  * adapters, the <ACE_Cleanup_Adapter> and <ACE_Managed_Object>
00079  * template classes for adapting objects of any type to be
00080  * easily managed by the <ACE_Object_Manager>.  There are several
00081  * mechanisms for adapting objects and arrays for cleanup at
00082  * program termination, in roughly increasing order of ease-of-use:
00083  * 1) Derive the object's class from <ACE_Cleanup>.
00084  * 2) Allow the <ACE_Object_Manager> to both dynamically allocate
00085  * and deallocate the object.
00086  * 3) Provide an <ACE_CLEANUP_FUNC> cleanup hook for the object or
00087  * array.
00088  * 4) Allow the <ACE_Object_Manager> to both preallocate the object
00089  * or array, either statically in global data or dynamically on
00090  * the heap, when its singleton instance is construction.
00091  *
00092  * There are also several mechanisms for registering objects and
00093  * arrays for cleanup.  In decreasing order of flexibility and
00094  * complexity (with the exception of the last mechanism):
00095  *
00096  * 1) ACE_Object_Manager::at_exit (void *object,
00097  * ACE_CLEANUP_FUNC cleanup_hook,
00098  * void *param);
00099  * can be used to register any object or array for any
00100  * cleanup activity at program termination.
00101  * 2) ACE_Object_Manager::at_exit (ACE_Cleanup *object,
00102  * void *param = 0);
00103  * can be used to register an <ACE_Cleanup> object
00104  * for any cleanup activity at program termination.
00105  * The final mechanism is not general purpose, but can only
00106  * be used to allocate objects and arrays at program startup:
00107  * 3) ACE_Managed_Object::get_preallocated_object
00108  * (ACE_Object_Manager::Preallocated_Object id);
00109  * and
00110  * ACE_Managed_Object::get_preallocated_array
00111  * (ACE_Object_Manager::Preallocated_Array id);
00112  * can only be used to allocate objects at program startup,
00113  * either in global data or on the heap (selected at compile
00114  * time).  These are intended to replace static locks, etc.
00115  * Instead of creating a static <ACE_Object_Manager> instance, one
00116  * can alternatively be created on the stack of the main program
00117  * thread.  It is created just after entry to ::main (int, char
00118  * *[]), and before any existing code in that function is
00119  * executed.  To enable this alternative, add #define
00120  * ACE_HAS_NONSTATIC_OBJECT_MANAGER before including the platform
00121  * specific config-* file in ace/config.h prior to
00122  * building the ACE library and your applications.  This #define
00123  * is enabled in some config files that are supplied with ACE.
00124  *
00125  * To ensure a static object manager is used, #undef
00126  * ACE_HAS_NONSTATIC_OBJECT_MANAGER *after* including the platform
00127  * specific config-* file.
00128  * Note that the ACE_Object_Manager _must_ be created before
00129  * any threads are spawned by the program.
00130  * If ACE_HAS_NONSTATIC_OBJECT_MANAGER is not #defined, the ACE
00131  * library creates a static, singleton <ACE_Object_Manager> instance.
00132  * The instance is placed in global program data, and constructed
00133  * via a static object constructor.  If ACE_HAS_NONSTATIC_OBJECT_MANAGER
00134  * is #defined, the <ACE_Object_Manager> instance is created on the stack
00135  * of the main program thread, as noted above.
00136  *
00137  * With ACE_HAS_NONSTATIC_OBJECT_MANAGER enabled, the ACE
00138  * library has no static objects that require destruction.
00139  * However, there are two drawbacks to using it:
00140  * 1) main (int, char *[]) must be declared with arguments, even
00141  * if they're not used.  All of ACE is converted to this, so
00142  * just applications have to be concerned with it.
00143  * 2) If there any static objects that depend on those that are
00144  * cleaned up by the Object_Manager, they'll get cleaned up too
00145  * late.  The ACE tests do not violate this requirement.
00146  * However, applications may have trouble with it.
00147  * NOTE on the use of <::exit> -- <::exit> does not destroy
00148  * automatic objects.  Therefore, if
00149  * ACE_HAS_NONSTATIC_OBJECT_MANAGER is enabled, the
00150  * <ACE_Object_Manager> instance will *not* be destroyed if
00151  * <::exit> is called!  However, <ACE_OS::exit> will properly
00152  * destroy the ACE_Object_Manager.  It is highly recommended
00153  * that <ACE_OS::exit> be used instead of <::exit>.
00154  *
00155  * However, <::exit> and <ACE_OS::exit> are tricky to use
00156  * properly, especially in multithread programs.  It is much
00157  * safer to throw an exception (or simulate that effect) that
00158  * will be caught by <main> instead of calling exit.  Then,
00159  * <main> can perform any necessary application-specific cleanup
00160  * and return the status value.  In addition, it's usually best
00161  * to avoid calling <::exit> and <ACE_OS::exit> from threads
00162  * other than the main thread.  Thanks to Jeff Greif
00163  * <jmg@trivida.com> for pointing out that <::exit> doesn't
00164  * destroy automatic objects, and for developing the
00165  * recommendations in this paragraph.
00166  *
00167  * Instead of creating a static <ACE_Object_Manager>, or letting
00168  * ACE create it on the stack of <main> for you, another
00169  * alternative is to #define
00170  * ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER.  With that
00171  * #define, the application must create the ACE_Object_Manager.
00172  * The recommended way is to call <ACE::init> at the start of
00173  * the program, and call <ACE::fini> at the end.  Alternatively,
00174  * the application could explicity construct an
00175  * <ACE_Object_Manager>.
00176  */
00177 class ACE_Export ACE_Object_Manager : public ACE_Object_Manager_Base
00178 {
00179 
00180 public:
00181   /**
00182    * Explicitly initialize (construct the singleton instance of) the
00183    * ACE_Object_Manager.  Returns 0 on success, -1 on failure, and 1
00184    * if it had already been called.
00185    */
00186   virtual int init (void);
00187 
00188   /**
00189    * Explicitly destroy the singleton instance of the
00190    * ACE_Object_Manager.  Returns 0 on success, -1 on failure, and 1
00191    * if it had already been called.
00192    */
00193   virtual int fini (void);
00194 
00195   /**
00196    * Returns 1 before the ACE_Object_Manager has been constructed.
00197    * This flag can be used to determine if the program is constructing
00198    * static objects.  If no static object spawns any threads, the
00199    * program will be single-threaded when this flag returns 1.  (Note
00200    * that the program still might construct some static objects when
00201    * this flag returns 0, if ACE_HAS_NONSTATIC_OBJECT_MANAGER is not
00202    * defined.)
00203    */
00204   static int starting_up (void);
00205 
00206   /**
00207    * Returns 1 after the ACE_Object_Manager has been destroyed.  This
00208    * flag can be used to determine if the program is in the midst of
00209    * destroying static objects.  (Note that the program might destroy
00210    * some static objects before this flag can return 1, if
00211    * ACE_HAS_NONSTATIC_OBJECT_MANAGER is not defined.)
00212    */
00213   static int shutting_down (void);
00214 
00215   /**
00216    * Register an ACE_Cleanup object for cleanup at process
00217    * termination.  The object is deleted via the
00218    * <ace_cleanup_destroyer>.  If you need more flexiblity, see the
00219    * <other at_exit> method below.  For OS's that do not have
00220    * processes, cleanup takes place at the end of <main>.  Returns 0
00221    * on success.  On failure, returns -1 and sets errno to: EAGAIN if
00222    * shutting down, ENOMEM if insufficient virtual memory, or EEXIST
00223    * if the object (or array) had already been registered.
00224    */
00225   static int at_exit (ACE_Cleanup *object, void *param = 0);
00226 
00227   /**
00228    * Register an object (or array) for cleanup at process termination.
00229    * "cleanup_hook" points to a (global, or static member) function
00230    * that is called for the object or array when it to be destroyed.
00231    * It may perform any necessary cleanup specific for that object or
00232    * its class.  "param" is passed as the second parameter to the
00233    * "cleanup_hook" function; the first parameter is the object (or
00234    * array) to be destroyed.  "cleanup_hook", for example, may delete
00235    * the object (or array).  For OS's that do not have processes, this
00236    * function is the same as <at_thread_exit>.  Returns 0 on success.
00237    * On failure, returns -1 and sets errno to: EAGAIN if shutting
00238    * down, ENOMEM if insufficient virtual memory, or EEXIST if the
00239    * object (or array) had already been registered.
00240    */
00241   static int at_exit (void *object,
00242                       ACE_CLEANUP_FUNC cleanup_hook,
00243                       void *param);
00244 
00245 #if 0 /* not implemented yet */
00246   /// Similar to <at_exit>, except that the cleanup_hook is called
00247   /// when the current thread exits instead of when the program terminates.
00248   static int at_thread_exit (void *object,
00249                              ACE_CLEANUP_FUNC cleanup_hook,
00250                              void *param);
00251 #endif /* 0 */
00252 
00253   /// Unique identifiers for preallocated objects.  Please see
00254   /// ace/Managed_Object.h for information on accessing preallocated
00255   /// objects.
00256   enum Preallocated_Object
00257     {
00258       ACE_FILECACHE_LOCK,
00259 #if defined (ACE_HAS_THREADS)
00260       ACE_STATIC_OBJECT_LOCK,
00261 #endif /* ACE_HAS_THREADS */
00262 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00263       ACE_MT_CORBA_HANDLER_LOCK,
00264       ACE_DUMP_LOCK,
00265       ACE_SIG_HANDLER_LOCK,
00266       ACE_SINGLETON_NULL_LOCK,
00267       ACE_SINGLETON_RECURSIVE_THREAD_LOCK,
00268       ACE_THREAD_EXIT_LOCK,
00269 #if !defined (ACE_LACKS_ACE_TOKEN)
00270       ACE_TOKEN_MANAGER_CREATION_LOCK,
00271       ACE_TOKEN_INVARIANTS_CREATION_LOCK,
00272 #endif /* ! ACE_LACKS_ACE_TOKEN */
00273       ACE_PROACTOR_EVENT_LOOP_LOCK,
00274 #endif /* ACE_MT_SAFE */
00275 
00276       // Hook for preallocated objects provided by application.
00277       ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS
00278 
00279       ACE_PREALLOCATED_OBJECTS  // This enum value must be last!
00280     };
00281 
00282   /// Unique identifiers for preallocated arrays.  Please see
00283   /// ace/Managed_Object.h for information on accessing preallocated
00284   /// arrays.
00285   enum Preallocated_Array
00286     {
00287       /// There currently are no preallocated arrays in the ACE
00288       /// library.  If the application doesn't have any, make sure
00289       /// the the preallocated_array size is at least one by declaring
00290       /// this dummy . . .
00291       ACE_EMPTY_PREALLOCATED_ARRAY,
00292 
00293       /// Hook for preallocated arrays provided by application.
00294       ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS
00295 
00296       ACE_PREALLOCATED_ARRAYS  // This enum value must be last!
00297     };
00298 
00299   /**
00300    * @deprecated Accesses a default signal set used, for example,
00301    * in ACE_Sig_Guard methods.
00302    * Deprecated: use ACE_Object_Manager::default_mask () instead.
00303    */
00304   static ACE_Sig_Set &default_mask (void);
00305 
00306 private:
00307   /// For at_exit support.
00308   ACE_OS_Exit_Info exit_info_;
00309 
00310 #if !defined (ACE_LACKS_ACE_SVCCONF)
00311   /// Preallocated objects collection.
00312   ACE_Object_Manager_Preallocations *preallocations_;
00313 
00314   /// ACE_Service_Config signal handler.
00315   ACE_Sig_Adapter *ace_service_config_sig_handler_;
00316 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00317 
00318   /// Register an object or array for deletion at program termination.
00319   /// See description of static version above for return values.
00320   int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);
00321 
00322 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00323 public:
00324   // = The <get_singleton_lock> accessors are for internal
00325   // use by ACE_Singleton _only_.
00326 
00327   /**
00328    * Accesses an <ACE_Null_Mutex> to be used for construction of
00329    * <ACE_Singletons>.  Returns 0, and the lock in the argument, on
00330    * success; returns -1 on failure.
00331    */
00332   static int get_singleton_lock (ACE_Null_Mutex *&);
00333 
00334   /**
00335    * Accesses a non-recursive <ACE_Thread_Mutex> to be used for
00336    * construction of <ACE_Singletons>.  Returns 0, and the lock in the
00337    * argument, on success; returns -1 on failure.
00338    */
00339   static int get_singleton_lock (ACE_Thread_Mutex *&);
00340 
00341   /**
00342    * Accesses a non-recursive <ACE_Mutex> to be used for construction
00343    * of <ACE_Singletons>.  Returns 0, and the lock in the argument, on
00344    * success; returns -1 on failure.
00345    */
00346   static int get_singleton_lock (ACE_Mutex *&);
00347 
00348   /**
00349    * Accesses a recursive <ACE_Recursive_Thread_Mutex> to be used for
00350    * construction of <ACE_Singletons>.  Returns 0, and the lock in the
00351    * argument, on success; returns -1 on failure.
00352    */
00353   static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&);
00354 
00355   /**
00356    * Accesses a readers/writer <ACE_RW_Thread_Mutex> to be used for
00357    * construction of <ACE_Singletons>.  Returns 0, and the lock in the
00358    * argument, on success; returns -1 on failure.
00359    */
00360   static int get_singleton_lock (ACE_RW_Thread_Mutex *&);
00361 #endif /* ACE_MT_SAFE */
00362 
00363 public:
00364   // For internal use only by ACE_Managed_Objects.
00365 
00366   /**
00367    * Accessor to singleton instance.  Because static member functions
00368    * are provided in the interface, this should not be public.  However,
00369    * it is public so that ACE_Managed_Object<TYPE> can access it.
00370    */
00371   static ACE_Object_Manager *instance (void);
00372 
00373   /// Table of preallocated objects.
00374   static void *preallocated_object[ACE_PREALLOCATED_OBJECTS];
00375 
00376   /// Table of preallocated arrays.
00377   static void *preallocated_array[ACE_PREALLOCATED_ARRAYS];
00378 
00379 public:
00380   // Application code should not use these explicitly, so they're
00381   // hidden here.  They're public so that the ACE_Object_Manager can
00382   // be constructed/destructed in <main> with
00383   // ACE_HAS_NONSTATIC_OBJECT_MANAGER.
00384   ACE_Object_Manager (void);
00385   ~ACE_Object_Manager (void);
00386 
00387 private:
00388   /// Singleton pointer.
00389   static ACE_Object_Manager *instance_;
00390 
00391 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00392   /// Lock that is used to guard internal structures.
00393   ACE_Recursive_Thread_Mutex *internal_lock_;
00394 
00395   /// Null lock for guarding singleton creation.
00396   ACE_Cleanup_Adapter<ACE_Null_Mutex> *singleton_null_lock_;
00397 
00398   /// Lock for guarding singleton creation, when Object_Manager
00399   /// hasn't been started up, or has already been shut down.
00400   ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> *singleton_recursive_lock_;
00401 #endif /* ACE_MT_SAFE */
00402 
00403 #if defined (ACE_HAS_TSS_EMULATION)
00404   // Main thread's thread-specific storage array.
00405   void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
00406 #endif /* ACE_HAS_TSS_EMULATION */
00407 
00408 #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
00409   friend class ACE_Object_Manager_Manager;
00410 #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */
00411 
00412   // Disallow copying by not implementing the following . . .
00413   ACE_Object_Manager (const ACE_Object_Manager &);
00414   ACE_Object_Manager &operator= (const ACE_Object_Manager &);
00415 };
00416 
00417 
00418 #if defined (ACE_HAS_THREADS)
00419 
00420 class ACE_Recursive_Thread_Mutex;
00421 
00422 /**
00423  * @class ACE_Static_Object_Lock
00424  *
00425  * @brief Provide an interface to access a global lock.
00426  *
00427  * This class is used to serialize the creation of static
00428  * singleton objects.  It really isn't needed any more, because
00429  * anyone can access ACE_STATIC_OBJECT_LOCK directly.  But, it
00430  * is retained for backward compatibility.
00431  */
00432 class ACE_Export ACE_Static_Object_Lock
00433 {
00434 public:
00435   /// Static lock access point.
00436   static ACE_Recursive_Thread_Mutex *instance (void);
00437 
00438   /// For use only by ACE_Object_Manager to clean up lock if it
00439   /// what dynamically allocated.
00440   static void cleanup_lock (void);
00441 };
00442 
00443 #endif /* ACE_HAS_THREADS */
00444 
00445 
00446 #if defined (__ACE_INLINE__)
00447 #include "ace/Object_Manager.i"
00448 #endif /* __ACE_INLINE__ */
00449 
00450 #include "ace/Managed_Object.h"
00451 
00452 #if !defined (ACE_LACKS_ACE_SVCCONF)
00453 // We can't use the ACE_SVC_FACTORY_DECLARE macro here because this
00454 // needs to be in the ACE_Export context rather than the
00455 // ACE_Svc_Export context.
00456 class ACE_Service_Object;
00457 extern "C" ACE_Export
00458 ACE_Service_Object *
00459 _make_ACE_Service_Manager (ACE_Service_Object_Exterminator *);
00460 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00461 
00462 // hack to get around errors while compiling using split-cpp
00463 #if defined (ACE_HAS_THREADS)
00464 
00465 # if defined (ACE_IS_SPLITTING)
00466 typedef ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> ACE_Static_Object_Lock_Type;
00467 
00468 #  if defined (__GNUC__)
00469 // With g++, suppress the warning that this is unused.
00470 static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock __attribute__ ((unused)) = 0;
00471 #  else
00472 static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock = 0;
00473 #  endif /* __GNUC__ */
00474 
00475 # endif /* ACE_IS_SPLITTING */
00476 
00477 #endif /* ACE_HAS_THREADS */
00478 
00479 #include "ace/post.h"
00480 #endif /* ACE_OBJECT_MANAGER_H */

Generated on Mon Jun 16 11:20:30 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002