00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Object_Manager.h 00006 * 00007 * $Id: Object_Manager.h 80826 2008-03-04 14:51:23Z wotte $ 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 #if defined (ACE_HAS_TSS_EMULATION) 00249 static int init_tss (void); 00250 int init_tss_i (void); 00251 #endif 00252 00253 /** 00254 * Register an object (or array) for cleanup at process termination. 00255 * "cleanup_hook" points to a (global, or static member) function 00256 * that is called for the object or array when it to be destroyed. 00257 * It may perform any necessary cleanup specific for that object or 00258 * its class. "param" is passed as the second parameter to the 00259 * "cleanup_hook" function; the first parameter is the object (or 00260 * array) to be destroyed. "cleanup_hook", for example, may delete 00261 * the object (or array). For OS's that do not have processes, this 00262 * function is the same as <at_thread_exit>. Returns 0 on success. 00263 * On failure, returns -1 and sets errno to: EAGAIN if shutting 00264 * down, ENOMEM if insufficient virtual memory, or EEXIST if the 00265 * object (or array) had already been registered. 00266 */ 00267 static int at_exit (void *object, 00268 ACE_CLEANUP_FUNC cleanup_hook, 00269 void *param); 00270 00271 #if 0 /* not implemented yet */ 00272 /// Similar to <at_exit>, except that the cleanup_hook is called 00273 /// when the current thread exits instead of when the program terminates. 00274 static int at_thread_exit (void *object, 00275 ACE_CLEANUP_FUNC cleanup_hook, 00276 void *param); 00277 #endif /* 0 */ 00278 00279 /// Unique identifiers for preallocated objects. Please see 00280 /// ace/Managed_Object.h for information on accessing preallocated 00281 /// objects. 00282 enum Preallocated_Object 00283 { 00284 ACE_FILECACHE_LOCK, 00285 #if defined (ACE_HAS_THREADS) 00286 ACE_STATIC_OBJECT_LOCK, 00287 #endif /* ACE_HAS_THREADS */ 00288 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00289 ACE_MT_CORBA_HANDLER_LOCK, 00290 ACE_DUMP_LOCK, 00291 ACE_SIG_HANDLER_LOCK, 00292 ACE_SINGLETON_NULL_LOCK, 00293 ACE_SINGLETON_RECURSIVE_THREAD_LOCK, 00294 ACE_THREAD_EXIT_LOCK, 00295 #if !defined (ACE_LACKS_ACE_TOKEN) 00296 ACE_TOKEN_MANAGER_CREATION_LOCK, 00297 ACE_TOKEN_INVARIANTS_CREATION_LOCK, 00298 #endif /* ! ACE_LACKS_ACE_TOKEN */ 00299 ACE_PROACTOR_EVENT_LOOP_LOCK, 00300 #endif /* ACE_MT_SAFE */ 00301 00302 // Hook for preallocated objects provided by application. 00303 ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS 00304 00305 ACE_PREALLOCATED_OBJECTS // This enum value must be last! 00306 }; 00307 00308 /// Unique identifiers for preallocated arrays. Please see 00309 /// ace/Managed_Object.h for information on accessing preallocated 00310 /// arrays. 00311 enum Preallocated_Array 00312 { 00313 /// There currently are no preallocated arrays in the ACE 00314 /// library. If the application doesn't have any, make sure 00315 /// the the preallocated_array size is at least one by declaring 00316 /// this dummy . . . 00317 ACE_EMPTY_PREALLOCATED_ARRAY, 00318 00319 /// Hook for preallocated arrays provided by application. 00320 ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS 00321 00322 ACE_PREALLOCATED_ARRAYS // This enum value must be last! 00323 }; 00324 00325 /** 00326 * @deprecated Accesses a default signal set used, for example, 00327 * in ACE_Sig_Guard methods. 00328 * Deprecated: use ACE_Object_Manager::default_mask () instead. 00329 */ 00330 static ACE_Sig_Set &default_mask (void); 00331 00332 private: 00333 /// For at_exit support. 00334 ACE_OS_Exit_Info exit_info_; 00335 00336 #if !defined (ACE_LACKS_ACE_SVCCONF) 00337 /// Preallocated objects collection. 00338 ACE_Object_Manager_Preallocations *preallocations_; 00339 00340 /// ACE_Service_Config signal handler. 00341 ACE_Sig_Adapter *ace_service_config_sig_handler_; 00342 #endif /* ! ACE_LACKS_ACE_SVCCONF */ 00343 00344 /// Register an object or array for deletion at program termination. 00345 /// See description of static version above for return values. 00346 int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); 00347 00348 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00349 public: 00350 // = The <get_singleton_lock> accessors are for internal 00351 // use by ACE_Singleton _only_. 00352 00353 /** 00354 * Accesses an ACE_Null_Mutex to be used for construction of 00355 * ACE_Singletons. Returns 0, and the lock in the argument, on 00356 * success; returns -1 on failure. 00357 */ 00358 static int get_singleton_lock (ACE_Null_Mutex *&); 00359 00360 /** 00361 * Accesses a non-recursive ACE_Thread_Mutex to be used for 00362 * construction of ACE_Singletons. Returns 0, and the lock in the 00363 * argument, on success; returns -1 on failure. 00364 */ 00365 static int get_singleton_lock (ACE_Thread_Mutex *&); 00366 00367 /** 00368 * Accesses a non-recursive ACE_Mutex to be used for construction 00369 * of ACE_Singletons. Returns 0, and the lock in the argument, on 00370 * success; returns -1 on failure. 00371 */ 00372 static int get_singleton_lock (ACE_Mutex *&); 00373 00374 /** 00375 * Accesses a recursive ACE_Recursive_Thread_Mutex to be used for 00376 * construction of ACE_Singletons. Returns 0, and the lock in the 00377 * argument, on success; returns -1 on failure. 00378 */ 00379 static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&); 00380 00381 /** 00382 * Accesses a readers/writer ACE_RW_Thread_Mutex to be used for 00383 * construction of ACE_Singletons. Returns 0, and the lock in the 00384 * argument, on success; returns -1 on failure. 00385 */ 00386 static int get_singleton_lock (ACE_RW_Thread_Mutex *&); 00387 #endif /* ACE_MT_SAFE */ 00388 00389 public: 00390 // For internal use only by ACE_Managed_Objects. 00391 00392 /** 00393 * Accessor to singleton instance. Because static member functions 00394 * are provided in the interface, this should not be public. However, 00395 * it is public so that ACE_Managed_Object<TYPE> can access it. 00396 */ 00397 static ACE_Object_Manager *instance (void); 00398 00399 /// Table of preallocated objects. 00400 static void *preallocated_object[ACE_PREALLOCATED_OBJECTS]; 00401 00402 /// Table of preallocated arrays. 00403 static void *preallocated_array[ACE_PREALLOCATED_ARRAYS]; 00404 00405 public: 00406 // Application code should not use these explicitly, so they're 00407 // hidden here. They're public so that the ACE_Object_Manager can 00408 // be constructed/destructed in <main> with 00409 // ACE_HAS_NONSTATIC_OBJECT_MANAGER. 00410 ACE_Object_Manager (void); 00411 ~ACE_Object_Manager (void); 00412 00413 private: 00414 /// Singleton pointer. 00415 static ACE_Object_Manager *instance_; 00416 00417 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00418 /// Lock that is used to guard internal structures. 00419 ACE_Recursive_Thread_Mutex *internal_lock_; 00420 00421 /// Null lock for guarding singleton creation. 00422 ACE_Cleanup_Adapter<ACE_Null_Mutex> *singleton_null_lock_; 00423 00424 /// Lock for guarding singleton creation, when Object_Manager 00425 /// hasn't been started up, or has already been shut down. 00426 ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> *singleton_recursive_lock_; 00427 #endif /* ACE_MT_SAFE */ 00428 00429 #if defined (ACE_HAS_TSS_EMULATION) 00430 // Main thread's thread-specific storage array. 00431 void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; 00432 bool ts_storage_initialized_; 00433 #endif /* ACE_HAS_TSS_EMULATION */ 00434 00435 #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) 00436 friend class ACE_Object_Manager_Manager; 00437 #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ 00438 00439 // Disallow copying by not implementing the following . . . 00440 ACE_Object_Manager (const ACE_Object_Manager &); 00441 ACE_Object_Manager &operator= (const ACE_Object_Manager &); 00442 }; 00443 00444 ACE_END_VERSIONED_NAMESPACE_DECL 00445 00446 #include "ace/Static_Object_Lock.h" 00447 00448 #if defined (__ACE_INLINE__) 00449 #include "ace/Object_Manager.inl" 00450 #endif /* __ACE_INLINE__ */ 00451 00452 #include "ace/Managed_Object.h" 00453 00454 #if !defined (ACE_LACKS_ACE_SVCCONF) 00455 // We can't use the ACE_SVC_FACTORY_DECLARE macro here because this 00456 // needs to be in the ACE_Export context rather than the 00457 // ACE_Svc_Export context. 00458 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00459 class ACE_Service_Object; 00460 ACE_END_VERSIONED_NAMESPACE_DECL 00461 ACE_FACTORY_DECLARE (ACE, ACE_Service_Manager) 00462 #endif /* ! ACE_LACKS_ACE_SVCCONF */ 00463 00464 00465 #include /**/ "ace/post.h" 00466 #endif /* ACE_OBJECT_MANAGER_H */