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 */
1.2.14 written by Dimitri van Heesch,
© 1997-2002