NAME

ACE_Object_Manager - Manager for ACE library services and singleton cleanup.

SYNOPSIS

#include <ace/Object_Manager.h>

class ACE_Object_Manager { public: static int at_exit (ACE_Cleanup *object, void *param = 0); static int at_exit ( void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param ); static int at_thread_exit ( void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param ); enum Preallocated_Object{ ACE_FILECACHE_LOCK, #if defined ( ACE_HAS_THREADS) ACE_STATIC_OBJECT_LOCK, #endif #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_LOG_MSG_INSTANCE_LOCK, ACE_MT_CORBA_HANDLER_LOCK, ACE_DUMP_LOCK, ACE_OS_MONITOR_LOCK, ACE_SIG_HANDLER_LOCK, ACE_SINGLETON_NULL_LOCK, ACE_SINGLETON_RECURSIVE_THREAD_LOCK, ACE_THREAD_EXIT_LOCK, ACE_TOKEN_MANAGER_CREATION_LOCK, ACE_TOKEN_INVARIANTS_CREATION_LOCK, ACE_TSS_CLEANUP_LOCK, #endif ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS ACE_PREALLOCATED_OBJECTS }; enum Preallocated_Array{ ACE_EMPTY_PREALLOCATED_ARRAY, ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS ACE_PREALLOCATED_ARRAYS }; static int starting_up (); static int shutting_down (); static ACE_Sig_Set &default_mask (void); static int get_singleton_lock (ACE_Null_Mutex *&); static int get_singleton_lock (ACE_Thread_Mutex *&); static int get_singleton_lock (ACE_Mutex *&); static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&); static int get_singleton_lock (ACE_RW_Thread_Mutex *&); ACE_Recursive_Thread_Mutex *lock_; static ACE_Object_Manager *instance (void); static void *managed_object[ACE_MAX_MANAGED_OBJECTS]; static u_int next_managed_object; static void *preallocated_object[ACE_PREALLOCATED_OBJECTS]; static void *preallocated_array[ACE_PREALLOCATED_ARRAYS]; ACE_Object_Manager (void); ~ACE_Object_Manager (void); private: ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_; int at_exit_i ( void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param ); static ACE_Object_Manager *instance_; static int starting_up_; static int shutting_down_; static ACE_Sig_Set *default_mask_p_; void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; friend class ACE_Object_Manager_Destroyer; ACE_Object_Manager (const ACE_Object_Manager &); ACE_Object_Manager &operator= (const ACE_Object_Manager &); };

DESCRIPTION

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 ACE_CLEANUP_FUNC 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 to ace/config.h prior to building the ACE library and your applications. This #define is enabled in the VxWorks config files that are supplied with ACE.

By default (except on VxWorks), 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. Optionally, the ACE_Object_Manager instance can be created on the stack of the main program thread. This option is enabled by added "#define ACE_HAS_NONSTATIC_OBJECT_MANAGER" to ace/config.h before building libACE. This option is enabled by default on VxWorks.

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.

PUBLIC MEMBERS

static int at_exit (ACE_Cleanup *object, void *param = 0);

static int at_exit (
    void *object,
    ACE_CLEANUP_FUNC cleanup_hook,
    void *param
    );

static int at_thread_exit (
    void *object,
    ACE_CLEANUP_FUNC cleanup_hook,
    void *param
    );

static int starting_up ();

static int shutting_down ();

static ACE_Sig_Set &default_mask (void);

static int get_singleton_lock (ACE_Null_Mutex *&);

static int get_singleton_lock (ACE_Thread_Mutex *&);

static int get_singleton_lock (ACE_Mutex *&);

static int get_singleton_lock (ACE_Recursive_Thread_Mutex *&);

static int get_singleton_lock (ACE_RW_Thread_Mutex *&);

ACE_Recursive_Thread_Mutex *lock_;

static ACE_Object_Manager *instance (void);

static void *managed_object[ACE_MAX_MANAGED_OBJECTS];

static u_int next_managed_object;

static void *preallocated_object[ACE_PREALLOCATED_OBJECTS];

static void *preallocated_array[ACE_PREALLOCATED_ARRAYS];

ACE_Object_Manager (void);

~ACE_Object_Manager (void);

PRIVATE MEMBERS

ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_;

int at_exit_i (
    void *object,
    ACE_CLEANUP_FUNC cleanup_hook,
    void *param
    );

static ACE_Object_Manager *instance_;

static int starting_up_;

static int shutting_down_;

static ACE_Sig_Set *default_mask_p_;

void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];

friend class ACE_Object_Manager_Destroyer;

ACE_Object_Manager (const ACE_Object_Manager &);

ACE_Object_Manager &operator= (const ACE_Object_Manager &);

AUTHORS

David L. Levine, Matthias Kerkhoff, and Per Andersson

LIBRARY

ace