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