/* -*- C++ -*- */ //============================================================================= /** * @file Object_Manager.h * * @author David L. Levine * @author Matthias Kerkhoff * @author Per Andersson */ //============================================================================= #ifndef ACE_OBJECT_MANAGER_H #define ACE_OBJECT_MANAGER_H #include /**/ "ace/pre.h" #include /**/ "ace/ACE_export.h" #include "ace/Object_Manager_Base.h" #include "ace/Global_Macros.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Forward declarations. class ACE_Object_Manager_Preallocations; class ACE_Sig_Adapter; class ACE_Sig_Set; ACE_END_VERSIONED_NAMESPACE_DECL #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_BEGIN_VERSIONED_NAMESPACE_DECL class ACE_Mutex; class ACE_Null_Mutex; class ACE_Thread_Mutex; class ACE_Recursive_Thread_Mutex; class ACE_RW_Thread_Mutex; ACE_END_VERSIONED_NAMESPACE_DECL # include "ace/Recursive_Thread_Mutex.h" #endif /* ACE_MT_SAFE */ ACE_BEGIN_VERSIONED_NAMESPACE_DECL // only used by ACE_OS_Object_Manager::ctor # if defined (ACE_WIN32) // Default WIN32 structured exception handler. int ACE_SEH_Default_Exception_Selector (void *); int ACE_SEH_Default_Exception_Handler (void *); # endif /* ACE_WIN32 */ class ACE_Cleanup_Info_Node; template class ACE_Cleanup_Adapter; // Configuration parameters. #if !defined (ACE_MAX_MANAGED_OBJECTS) # define ACE_MAX_MANAGED_OBJECTS 128 #endif /* ! ACE_MAX_MANAGED_OBJECTS */ #if !defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS) # define ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS #endif /* ! ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS */ #if !defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS) # define ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS #endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */ /** * @class ACE_Object_Manager * * @brief Manager for ACE library services and singleton cleanup. * * The ACE_Object_Manager manages cleanup of objects, typically * singletons, at program termination. In addition to managing * the cleanup of the ACE library, it provides an interface for * application to register objects to be cleaned up. * This class also shuts down ACE library services, so that they * can reclaim their storage, at program termination. It works * by creating a static instance whose destructor gets called * along with those of all other static objects. Hooks are * provided for application code to register objects and arrays * for cleanup, e.g., destruction. The order of such cleanup * calls is in the reverse order of registration, i.e., that * last object/array to register gets cleaned up first. * The ACE_Object_Manager API includes ACE_Managed_Object. That * class is contained in a separate file because it is a * template class, and some compilers require that template and * non-template class definitions appear in separate files. * Please see ace/Managed_Object.h for a description of that * part of the API. In summary, ACE_Managed_Object provides two * adapters, the ACE_Cleanup_Adapter and ACE_Managed_Object * template classes for adapting objects of any type to be * easily managed by the ACE_Object_Manager. There are several * mechanisms for adapting objects and arrays for cleanup at * program termination, in roughly increasing order of ease-of-use: * 1) Derive the object's class from ACE_Cleanup. * 2) Allow the ACE_Object_Manager to both dynamically allocate * and deallocate the object. * 3) Provide an cleanup hook for the object or * array. * 4) Allow the ACE_Object_Manager to both preallocate the object * or array, either statically in global data or dynamically on * the heap, when its singleton instance is construction. * * There are also several mechanisms for registering objects and * arrays for cleanup. In decreasing order of flexibility and * complexity (with the exception of the last mechanism): * * 1) ACE_Object_Manager::at_exit (void *object, * ACE_CLEANUP_FUNC cleanup_hook, * void *param); * can be used to register any object or array for any * cleanup activity at program termination. * 2) ACE_Object_Manager::at_exit (ACE_Cleanup *object, * void *param = 0); * can be used to register an ACE_Cleanup object * for any cleanup activity at program termination. * The final mechanism is not general purpose, but can only * be used to allocate objects and arrays at program startup: * 3) ACE_Managed_Object::get_preallocated_object * (ACE_Object_Manager::Preallocated_Object id); * and * ACE_Managed_Object::get_preallocated_array * (ACE_Object_Manager::Preallocated_Array id); * can only be used to allocate objects at program startup, * either in global data or on the heap (selected at compile * time). These are intended to replace static locks, etc. * Instead of creating a static ACE_Object_Manager instance, one * can alternatively be created on the stack of the main program * thread. It is created just after entry to ::main (int, char * *[]), and before any existing code in that function is * executed. To enable this alternative, add #define * ACE_HAS_NONSTATIC_OBJECT_MANAGER before including the platform * specific config-* file in ace/config.h prior to * building the ACE library and your applications. This #define * is enabled in some config files that are supplied with ACE. * * To ensure a static object manager is used, #undef * ACE_HAS_NONSTATIC_OBJECT_MANAGER *after* including the platform * specific config-* file. * Note that the ACE_Object_Manager _must_ be created before * any threads are spawned by the program. * If ACE_HAS_NONSTATIC_OBJECT_MANAGER is not #defined, the ACE * library creates a static, singleton ACE_Object_Manager instance. * The instance is placed in global program data, and constructed * via a static object constructor. If ACE_HAS_NONSTATIC_OBJECT_MANAGER * is #defined, the ACE_Object_Manager instance is created on the stack * of the main program thread, as noted above. * * With ACE_HAS_NONSTATIC_OBJECT_MANAGER enabled, the ACE * library has no static objects that require destruction. * However, there are two drawbacks to using it: * 1) main (int, char *[]) must be declared with arguments, even * if they're not used. All of ACE is converted to this, so * just applications have to be concerned with it. * 2) If there any static objects that depend on those that are * cleaned up by the Object_Manager, they'll get cleaned up too * late. The ACE tests do not violate this requirement. * However, applications may have trouble with it. * NOTE on the use of <::exit> -- <::exit> does not destroy * automatic objects. Therefore, if * ACE_HAS_NONSTATIC_OBJECT_MANAGER is enabled, the * ACE_Object_Manager instance will *not* be destroyed if * <::exit> is called! However, will properly * destroy the ACE_Object_Manager. It is highly recommended * that be used instead of <::exit>. * * However, <::exit> and are tricky to use * properly, especially in multithread programs. It is much * safer to throw an exception (or simulate that effect) that * will be caught by
instead of calling exit. Then, *
can perform any necessary application-specific cleanup * and return the status value. In addition, it's usually best * to avoid calling <::exit> and from threads * other than the main thread. Thanks to Jeff Greif * for pointing out that <::exit> doesn't * destroy automatic objects, and for developing the * recommendations in this paragraph. * * Instead of creating a static ACE_Object_Manager, or letting * ACE create it on the stack of
for you, another * alternative is to #define * ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER. With that * #define, the application must create the ACE_Object_Manager. * The recommended way is to call at the start of * the program, and call at the end. Alternatively, * the application could explicity construct an * ACE_Object_Manager. */ class ACE_Export ACE_Object_Manager : public ACE_Object_Manager_Base { public: ACE_ALLOC_HOOK_DECLARE; /** * Explicitly initialize (construct the singleton instance of) the * ACE_Object_Manager. Returns 0 on success, -1 on failure, and 1 * if it had already been called. */ virtual int init (); /** * Explicitly destroy the singleton instance of the * ACE_Object_Manager. Returns 0 on success, -1 on failure, and 1 * if it had already been called. */ virtual int fini (); /** * Returns 1 before the ACE_Object_Manager has been constructed. * This flag can be used to determine if the program is constructing * static objects. If no static object spawns any threads, the * program will be single-threaded when this flag returns 1. (Note * that the program still might construct some static objects when * this flag returns 0, if ACE_HAS_NONSTATIC_OBJECT_MANAGER is not * defined.) */ static int starting_up (); /** * Returns 1 after the ACE_Object_Manager has been destroyed. This * flag can be used to determine if the program is in the midst of * destroying static objects. (Note that the program might destroy * some static objects before this flag can return 1, if * ACE_HAS_NONSTATIC_OBJECT_MANAGER is not defined.) */ static int shutting_down (); /** * Register an ACE_Cleanup object for cleanup at process * termination. The object is deleted via the * . If you need more flexibility, see the * @c other at_exit method below. For OS's that do not have * processes, cleanup takes place at the end of
. Returns 0 * on success. On failure, returns -1 and sets errno to: EAGAIN if * shutting down, ENOMEM if insufficient virtual memory, or EEXIST * if the object (or array) had already been registered. */ static int at_exit (ACE_Cleanup *object, void *param = 0, const char* name = 0); #if defined (ACE_HAS_TSS_EMULATION) static int init_tss (void); int init_tss_i (void); #endif /** * Register an object (or array) for cleanup at process termination. * "cleanup_hook" points to a (global, or static member) function * that is called for the object or array when it to be destroyed. * It may perform any necessary cleanup specific for that object or * its class. "param" is passed as the second parameter to the * @a cleanup_hook function; the first parameter is the object (or * array) to be destroyed. @a cleanup_hook, for example, may delete * the object (or array). For OS's that do not have processes, this * function is the same as . Returns 0 on success. * On failure, returns -1 and sets errno to: EAGAIN if shutting * down, ENOMEM if insufficient virtual memory, or EEXIST if the * object (or array) had already been registered. */ static int at_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param, const char* name = 0); static int remove_at_exit (void *object); #if 0 /* not implemented yet */ /// Similar to at_exit(), except that the cleanup_hook is called /// when the current thread exits instead of when the program terminates. static int at_thread_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param, const char* name); #endif /* 0 */ /// Unique identifiers for preallocated objects. Please see /// ace/Managed_Object.h for information on accessing preallocated /// objects. enum Preallocated_Object { ACE_FILECACHE_LOCK, #if defined (ACE_HAS_THREADS) ACE_STATIC_OBJECT_LOCK, #endif /* ACE_HAS_THREADS */ #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_MT_CORBA_HANDLER_LOCK, ACE_DUMP_LOCK, ACE_SIG_HANDLER_LOCK, ACE_SINGLETON_NULL_LOCK, ACE_SINGLETON_RECURSIVE_THREAD_LOCK, ACE_THREAD_EXIT_LOCK, #if !defined (ACE_LACKS_ACE_TOKEN) ACE_TOKEN_MANAGER_CREATION_LOCK, ACE_TOKEN_INVARIANTS_CREATION_LOCK, #endif /* ! ACE_LACKS_ACE_TOKEN */ ACE_PROACTOR_EVENT_LOOP_LOCK, #endif /* ACE_MT_SAFE */ // Hook for preallocated objects provided by application. ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS ACE_PREALLOCATED_OBJECTS // This enum value must be last! }; /// Unique identifiers for preallocated arrays. Please see /// ace/Managed_Object.h for information on accessing preallocated /// arrays. enum Preallocated_Array { /// There currently are no preallocated arrays in the ACE /// library. If the application doesn't have any, make sure /// the the preallocated_array size is at least one by declaring /// this dummy . . . ACE_EMPTY_PREALLOCATED_ARRAY, /// Hook for preallocated arrays provided by application. ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS ACE_PREALLOCATED_ARRAYS // This enum value must be last! }; /** * @deprecated * Accesses a default signal set used, for example, * in ACE_Sig_Guard methods. * Deprecated: use ACE_Object_Manager::default_mask () instead. */ static ACE_Sig_Set &default_mask (); private: /// For at_exit support. ACE_OS_Exit_Info exit_info_; #if !defined (ACE_LACKS_ACE_SVCCONF) /// Preallocated objects collection. ACE_Object_Manager_Preallocations *preallocations_; /// ACE_Service_Config signal handler. ACE_Sig_Adapter *ace_service_config_sig_handler_; #endif /* ! ACE_LACKS_ACE_SVCCONF */ /// Register an object or array for deletion at program termination. /// See description of static version above for return values. int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param, const char* name); /// Remove an object for deletion at program termination. /// See description of static version above for return values. int remove_at_exit_i (void *object); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) public: // = The accessors are for internal // use by ACE_Singleton _only_. /** * Accesses an ACE_Null_Mutex to be used for construction of * ACE_Singletons. Returns 0, and the lock in the argument, on * success; returns -1 on failure. */ static int get_singleton_lock (ACE_Null_Mutex *&); /** * Accesses a non-recursive ACE_Thread_Mutex to be used for * construction of ACE_Singletons. Returns 0, and the lock in the * argument, on success; returns -1 on failure. */ static int get_singleton_lock (ACE_Thread_Mutex *&); /** * Accesses a non-recursive ACE_Mutex to be used for construction * of ACE_Singletons. Returns 0, and the lock in the argument, on * success; returns -1 on failure. */ static int get_singleton_lock (ACE_Mutex *&); /** * Accesses a recursive ACE_Recursive_Thread_Mutex to be used for * construction of ACE_Singletons. Returns 0, and the lock in the * argument, on success; returns -1 on failure. */ static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&); /** * Accesses a readers/writer ACE_RW_Thread_Mutex to be used for * construction of ACE_Singletons. Returns 0, and the lock in the * argument, on success; returns -1 on failure. */ static int get_singleton_lock (ACE_RW_Thread_Mutex *&); #endif /* ACE_MT_SAFE */ public: // For internal use only by ACE_Managed_Objects. /** * Accessor to singleton instance. Because static member functions * are provided in the interface, this should not be public. However, * it is public so that ACE_Managed_Object can access it. */ static ACE_Object_Manager *instance (); /// Table of preallocated objects. static void *preallocated_object[ACE_PREALLOCATED_OBJECTS]; /// Table of preallocated arrays. static void *preallocated_array[ACE_PREALLOCATED_ARRAYS]; public: /// Application code should not use these explicitly, so they're /// hidden here. They're public so that the ACE_Object_Manager can /// be constructed/destructed in
with /// ACE_HAS_NONSTATIC_OBJECT_MANAGER. ACE_Object_Manager (); ~ACE_Object_Manager (); private: /// Singleton pointer. static ACE_Object_Manager *instance_; #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) /// Lock that is used to guard internal structures. ACE_Recursive_Thread_Mutex *internal_lock_; /// Null lock for guarding singleton creation. ACE_Cleanup_Adapter *singleton_null_lock_; /// Lock for guarding singleton creation, when Object_Manager /// hasn't been started up, or has already been shut down. ACE_Cleanup_Adapter *singleton_recursive_lock_; #endif /* ACE_MT_SAFE */ #if defined (ACE_HAS_TSS_EMULATION) /// Main thread's thread-specific storage array. void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; bool ts_storage_initialized_; #endif /* ACE_HAS_TSS_EMULATION */ #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) friend class ACE_Object_Manager_Manager; #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ ACE_Object_Manager (const ACE_Object_Manager &) = delete; ACE_Object_Manager &operator= (const ACE_Object_Manager &) = delete; ACE_Object_Manager (ACE_Object_Manager &&) = delete; ACE_Object_Manager &operator= (ACE_Object_Manager &&) = delete; }; ACE_END_VERSIONED_NAMESPACE_DECL #include "ace/Static_Object_Lock.h" #if defined (__ACE_INLINE__) #include "ace/Object_Manager.inl" #endif /* __ACE_INLINE__ */ #include "ace/Managed_Object.h" #if !defined (ACE_LACKS_ACE_SVCCONF) // We can't use the ACE_SVC_FACTORY_DECLARE macro here because this // needs to be in the ACE_Export context rather than the // ACE_Svc_Export context. ACE_BEGIN_VERSIONED_NAMESPACE_DECL class ACE_Service_Object; ACE_END_VERSIONED_NAMESPACE_DECL ACE_FACTORY_DECLARE (ACE, ACE_Service_Manager) #endif /* ! ACE_LACKS_ACE_SVCCONF */ #include /**/ "ace/post.h" #endif /* ACE_OBJECT_MANAGER_H */