diff options
author | dhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-05-02 09:41:57 +0000 |
---|---|---|
committer | dhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-05-02 09:41:57 +0000 |
commit | b18fc6910822dc6fa21efbd8b5461d9d675d2eac (patch) | |
tree | 2c798230eba0af0878d5611ede3cb90e56f8d4a0 | |
parent | a01355f6d12d47d52ebbbdd489477b7c19e5f8c7 (diff) | |
download | ATCD-b18fc6910822dc6fa21efbd8b5461d9d675d2eac.tar.gz |
ChangeLogTag:Thu May 2 09:11:17 UTC 2002 Don Hinton <dhinton@ieee.org>
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-02a | 25 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 25 | ||||
-rw-r--r-- | ace/Init_ACE.cpp | 1 | ||||
-rw-r--r-- | ace/Makefile | 1 | ||||
-rw-r--r-- | ace/OS.cpp | 629 | ||||
-rw-r--r-- | ace/OS.h | 406 | ||||
-rw-r--r-- | ace/OS.i | 6 | ||||
-rw-r--r-- | ace/OS_Thread_Adapter.cpp | 1 | ||||
-rw-r--r-- | ace/Object_Manager.h | 4 | ||||
-rw-r--r-- | ace/Object_Manager_Base.cpp | 643 | ||||
-rw-r--r-- | ace/Object_Manager_Base.h | 362 | ||||
-rw-r--r-- | ace/Signal.i | 2 | ||||
-rw-r--r-- | ace/Singleton.h | 2 | ||||
-rw-r--r-- | ace/Thread_Hook.cpp | 2 | ||||
-rw-r--r-- | ace/Trace.cpp | 2 |
16 files changed, 1096 insertions, 1040 deletions
diff --git a/ChangeLog b/ChangeLog index 53dae0bdb10..a5a6b6c7f00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,31 @@ +Thu May 2 09:11:17 UTC 2002 Don Hinton <dhinton@ieee.org> + + * ace/Init_ACE.cpp: + * ace/OS_Thread_Adapter.cpp: + * ace/Object_Manager.h: + * ace/Signal.i: + * ace/Singleton.h: + * ace/Thread_Hook.cpp: + * ace/Trace.cpp: + + Fixed includes related to moved classes below. + + * ace/Object_Manager_Base.{h,cpp}: + * ace/OS.{h,cpp,i}: + * ace/Makefile + + Moved ACE_Cleanup*, ACE_Object_Manager_Base, and ACE_OS_Object_Manager + from OS.h to new files. + + * ace/Object_Manager_Base.{h,cpp}: + + Added new files. + Fri Apr 26 12:31:10 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/*.{h,i,cpp}: - Move included in cpp after include of inline. + Moved includes in cpp after include of inline. Reorded includes in *.cpp files so that all includes, except for the corresponding *.h file, come after the conditional diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index 53dae0bdb10..a5a6b6c7f00 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,8 +1,31 @@ +Thu May 2 09:11:17 UTC 2002 Don Hinton <dhinton@ieee.org> + + * ace/Init_ACE.cpp: + * ace/OS_Thread_Adapter.cpp: + * ace/Object_Manager.h: + * ace/Signal.i: + * ace/Singleton.h: + * ace/Thread_Hook.cpp: + * ace/Trace.cpp: + + Fixed includes related to moved classes below. + + * ace/Object_Manager_Base.{h,cpp}: + * ace/OS.{h,cpp,i}: + * ace/Makefile + + Moved ACE_Cleanup*, ACE_Object_Manager_Base, and ACE_OS_Object_Manager + from OS.h to new files. + + * ace/Object_Manager_Base.{h,cpp}: + + Added new files. + Fri Apr 26 12:31:10 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/*.{h,i,cpp}: - Move included in cpp after include of inline. + Moved includes in cpp after include of inline. Reorded includes in *.cpp files so that all includes, except for the corresponding *.h file, come after the conditional diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index 53dae0bdb10..a5a6b6c7f00 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,8 +1,31 @@ +Thu May 2 09:11:17 UTC 2002 Don Hinton <dhinton@ieee.org> + + * ace/Init_ACE.cpp: + * ace/OS_Thread_Adapter.cpp: + * ace/Object_Manager.h: + * ace/Signal.i: + * ace/Singleton.h: + * ace/Thread_Hook.cpp: + * ace/Trace.cpp: + + Fixed includes related to moved classes below. + + * ace/Object_Manager_Base.{h,cpp}: + * ace/OS.{h,cpp,i}: + * ace/Makefile + + Moved ACE_Cleanup*, ACE_Object_Manager_Base, and ACE_OS_Object_Manager + from OS.h to new files. + + * ace/Object_Manager_Base.{h,cpp}: + + Added new files. + Fri Apr 26 12:31:10 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/*.{h,i,cpp}: - Move included in cpp after include of inline. + Moved includes in cpp after include of inline. Reorded includes in *.cpp files so that all includes, except for the corresponding *.h file, come after the conditional diff --git a/ace/Init_ACE.cpp b/ace/Init_ACE.cpp index d9aa05e3120..c01d5141d15 100644 --- a/ace/Init_ACE.cpp +++ b/ace/Init_ACE.cpp @@ -5,6 +5,7 @@ #endif /* ACE_LACKS_INLINE_FUNCTIONS */ #include "ace/Object_Manager.h" +#include "ace/Trace.h" ACE_RCSID (ace, Init_ACE, diff --git a/ace/Makefile b/ace/Makefile index 16f2c9d9643..880f5454c7e 100644 --- a/ace/Makefile +++ b/ace/Makefile @@ -55,6 +55,7 @@ UTILS_FILES = \ Message_Block \ Method_Request \ Object_Manager \ + Object_Manager_Base \ Registry \ String_Base_Const \ SString \ diff --git a/ace/OS.cpp b/ace/OS.cpp index d10c9cc43eb..b662fddc08f 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -234,155 +234,7 @@ ACE_OS::netdb_release (void) # define ACE_TSS_BASE_GUARD #endif /* ! ACE_MT_SAFE */ -ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0; -ACE_Cleanup_Info::ACE_Cleanup_Info (void) - : object_ (0), - cleanup_hook_ (0), - param_ (0) -{ -} - -int -ACE_Cleanup_Info::operator== (const ACE_Cleanup_Info &o) const -{ - return o.object_ == this->object_ - && o.cleanup_hook_ == this->cleanup_hook_ - && o.param_ == this->param_; -} - -int -ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const -{ - return !(*this == o); -} - -class ACE_Cleanup_Info_Node -{ - // = TITLE - // For maintaining a list of ACE_Cleanup_Info items. - // - // = DESCRIPTION - // For internal use by ACE_Object_Manager. -public: - ACE_Cleanup_Info_Node (void); - ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, - ACE_Cleanup_Info_Node *next); - ~ACE_Cleanup_Info_Node (void); - ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &); -private: - ACE_Cleanup_Info cleanup_info_; - ACE_Cleanup_Info_Node *next_; - - friend class ACE_OS_Exit_Info; -}; - -ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void) - : cleanup_info_ (), - next_ (0) -{ -} - -ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, - ACE_Cleanup_Info_Node *next) - : cleanup_info_ (new_info), - next_ (next) -{ -} - -ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void) -{ - delete next_; -} - -ACE_Cleanup_Info_Node * -ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info) -{ - ACE_Cleanup_Info_Node *new_node; - - ACE_NEW_RETURN (new_node, - ACE_Cleanup_Info_Node (new_info, this), - 0); - - return new_node; -} - -ACE_OS_Exit_Info::ACE_OS_Exit_Info (void) -{ - ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node); -} - -ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void) -{ - delete registered_objects_; - registered_objects_ = 0; -} - -int -ACE_OS_Exit_Info::at_exit_i (void *object, - ACE_CLEANUP_FUNC cleanup_hook, - void *param) -{ - ACE_Cleanup_Info new_info; - new_info.object_ = object; - new_info.cleanup_hook_ = cleanup_hook; - new_info.param_ = param; - - // Return -1 and sets errno if unable to allocate storage. Enqueue - // at the head and dequeue from the head to get LIFO ordering. - - ACE_Cleanup_Info_Node *new_node; - - if ((new_node = registered_objects_->insert (new_info)) == 0) - return -1; - else - { - registered_objects_ = new_node; - return 0; - } -} - -int -ACE_OS_Exit_Info::find (void *object) -{ - // Check for already in queue, and return 1 if so. - for (ACE_Cleanup_Info_Node *iter = registered_objects_; - iter && iter->next_ != 0; - iter = iter->next_) - { - if (iter->cleanup_info_.object_ == object) - { - // The object has already been registered. - return 1; - } - } - - return 0; -} - -void -ACE_OS_Exit_Info::call_hooks () -{ - // Call all registered cleanup hooks, in reverse order of - // registration. - for (ACE_Cleanup_Info_Node *iter = registered_objects_; - iter && iter->next_ != 0; - iter = iter->next_) - { - ACE_Cleanup_Info &info = iter->cleanup_info_; - if (info.cleanup_hook_ == ACE_reinterpret_cast (ACE_CLEANUP_FUNC, - ace_cleanup_destroyer)) - // The object is an ACE_Cleanup. - ace_cleanup_destroyer (ACE_reinterpret_cast (ACE_Cleanup *, - info.object_), - info.param_); - else if (info.object_ == &ace_exit_hook_marker) - // The hook is an ACE_EXIT_HOOK. - (* ACE_reinterpret_cast (ACE_EXIT_HOOK, info.cleanup_hook_)) (); - else - (*info.cleanup_hook_) (info.object_, info.param_); - } -} ACE_Countdown_Time::ACE_Countdown_Time (ACE_Time_Value *max_wait_time) : max_wait_time_ (max_wait_time), @@ -2349,12 +2201,6 @@ int ACE_SEH_Default_Exception_Handler (void *) } #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ -extern "C" void -ace_cleanup_destroyer (ACE_Cleanup *object, void *param) -{ - object->cleanup (param); -} - int ACE_OS::thr_create (ACE_THR_FUNC func, void *args, @@ -4522,17 +4368,6 @@ ACE_OS::fork (const ACE_TCHAR *program_name) #endif /* ACE_WIN32 */ } -void -ACE_Cleanup::cleanup (void *) -{ - delete this; -} - - -ACE_Cleanup::~ACE_Cleanup (void) -{ -} - // This is necessary to work around nasty problems with MVS C++. extern "C" void @@ -6267,470 +6102,6 @@ extern "C" int __d10_sigwait (const sigset_t *set, int *sig) } #endif /* __DGUX && PTHREADS && _POSIX4A_DRAFT10_SOURCE */ -#define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\ - {\ - TYPE *obj_p = 0;\ - ACE_NEW_RETURN (obj_p, TYPE, -1);\ - preallocated_object[ID] = (void *) obj_p;\ - } -#define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\ - delete (TYPE *) preallocated_object[ID];\ - preallocated_object[ID] = 0; - -ACE_Object_Manager_Base::ACE_Object_Manager_Base (void) - : object_manager_state_ (OBJ_MAN_UNINITIALIZED) - , dynamically_allocated_ (0) - , next_ (0) -{ -} - -ACE_Object_Manager_Base::~ACE_Object_Manager_Base (void) -{ -#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) - // Clear the flag so that fini () doesn't delete again. - dynamically_allocated_ = 0; -#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ -} - -int -ACE_Object_Manager_Base::starting_up_i () -{ - return object_manager_state_ < OBJ_MAN_INITIALIZED; -} - -int -ACE_Object_Manager_Base::shutting_down_i () -{ - return object_manager_state_ > OBJ_MAN_INITIALIZED; -} - -extern "C" -void -ACE_OS_Object_Manager_Internal_Exit_Hook (void) -{ - if (ACE_OS_Object_Manager::instance_) - ACE_OS_Object_Manager::instance ()->fini (); -} - -ACE_OS_Object_Manager *ACE_OS_Object_Manager::instance_ = 0; - -void *ACE_OS_Object_Manager::preallocated_object[ - ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS] = { 0 }; - -ACE_OS_Object_Manager::ACE_OS_Object_Manager (void) - // default_mask_ isn't initialized, because it's defined by <init>. - : thread_hook_ (0) - , exit_info_ () -#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) - , seh_except_selector_ (ACE_SEH_Default_Exception_Selector) - , seh_except_handler_ (ACE_SEH_Default_Exception_Handler) -#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ -{ - // If instance_ was not 0, then another ACE_OS_Object_Manager has - // already been instantiated (it is likely to be one initialized by - // way of library/DLL loading). Let this one go through - // construction in case there really is a good reason for it (like, - // ACE is a static/archive library, and this one is the non-static - // instance (with ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has - // a good reason for creating a separate one) but the original one - // will be the one retrieved from calls to - // ACE_Object_Manager::instance(). - - // Be sure that no further instances are created via instance (). - if (instance_ == 0) - instance_ = this; - - init (); -} - -ACE_OS_Object_Manager::~ACE_OS_Object_Manager (void) -{ - dynamically_allocated_ = 0; // Don't delete this again in fini() - fini (); -} - -sigset_t * -ACE_OS_Object_Manager::default_mask (void) -{ - return ACE_OS_Object_Manager::instance ()->default_mask_; -} - -ACE_Thread_Hook * -ACE_OS_Object_Manager::thread_hook (void) -{ - return ACE_OS_Object_Manager::instance ()->thread_hook_; -} - -#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) -ACE_SEH_EXCEPT_HANDLER -ACE_OS_Object_Manager::seh_except_selector (void) -{ - return ACE_OS_Object_Manager::instance ()->seh_except_selector_; -} - -ACE_SEH_EXCEPT_HANDLER -ACE_OS_Object_Manager::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n) -{ - ACE_OS_Object_Manager *instance = - ACE_OS_Object_Manager::instance (); - - ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_selector_; - instance->seh_except_selector_ = n; - return retv; -} - -ACE_SEH_EXCEPT_HANDLER -ACE_OS_Object_Manager::seh_except_handler (void) -{ - return ACE_OS_Object_Manager::instance ()->seh_except_handler_; -} - -ACE_SEH_EXCEPT_HANDLER -ACE_OS_Object_Manager::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n) -{ - ACE_OS_Object_Manager *instance = - ACE_OS_Object_Manager::instance (); - - ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_handler_; - instance->seh_except_handler_ = n; - return retv; -} -#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ - -ACE_Thread_Hook * -ACE_OS_Object_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook) -{ - ACE_OS_Object_Manager *os_om = ACE_OS_Object_Manager::instance (); - ACE_Thread_Hook *old_hook = os_om->thread_hook_; - os_om->thread_hook_ = new_thread_hook; - return old_hook; -} - -ACE_OS_Object_Manager * -ACE_OS_Object_Manager::instance (void) -{ - // This function should be called during construction of static - // instances, or before any other threads have been created in the - // process. So, it's not thread safe. - - if (instance_ == 0) - { - ACE_OS_Object_Manager *instance_pointer; - - ACE_NEW_RETURN (instance_pointer, - ACE_OS_Object_Manager, - 0); - // I (coryan) removed it, using asserts in the OS layer - // brings down the Log msg stuff - // ACE_ASSERT (instance_pointer == instance_); - - instance_pointer->dynamically_allocated_ = 1; - - } - - return instance_; -} - -int -ACE_OS_Object_Manager::init (void) -{ - if (starting_up_i ()) - { - // First, indicate that this ACE_OS_Object_Manager instance is being - // initialized. - object_manager_state_ = OBJ_MAN_INITIALIZING; - - if (this == instance_) - { -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) -# if defined (ACE_HAS_WINCE_BROKEN_ERRNO) - ACE_CE_Errno::init (); -# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */ - ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK) - if (ACE_OS::thread_mutex_init - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK")); - ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_CLEANUP_LOCK) - if (ACE_OS::recursive_mutex_init - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK")); - ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, - ACE_LOG_MSG_INSTANCE_LOCK) - if (ACE_OS::thread_mutex_init - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_LOG_MSG_INSTANCE_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK")); -# if defined (ACE_HAS_TSS_EMULATION) - ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_KEY_LOCK) - if (ACE_OS::recursive_mutex_init - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK")); -# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) - ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_BASE_LOCK) - if (ACE_OS::recursive_mutex_init - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK")); -# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ -# endif /* ACE_HAS_TSS_EMULATION */ -#endif /* ACE_MT_SAFE */ - - // Open Winsock (no-op on other platforms). - ACE_OS::socket_init (ACE_WSOCK_VERSION); - - // Register the exit hook, for use by ACE_OS::exit (). - ACE_OS::set_exit_hook (&ACE_OS_Object_Manager_Internal_Exit_Hook); - } - - ACE_NEW_RETURN (default_mask_, sigset_t, -1); - ACE_OS::sigfillset (default_mask_); - - // Finally, indicate that the ACE_OS_Object_Manager instance has - // been initialized. - object_manager_state_ = OBJ_MAN_INITIALIZED; - -#if defined (ACE_WIN32) - ACE_OS::win32_versioninfo_.dwOSVersionInfoSize = - sizeof (OSVERSIONINFO); - ::GetVersionEx (&ACE_OS::win32_versioninfo_); -#endif /* ACE_WIN32 */ - return 0; - } else { - // Had already initialized. - return 1; - } -} - -// Clean up an ACE_OS_Object_Manager. There can be instances of this object -// other than The Instance. This can happen if a user creates one for some -// reason. All objects clean up their per-object information and managed -// objects, but only The Instance cleans up the static preallocated objects. -int -ACE_OS_Object_Manager::fini (void) -{ - if (instance_ == 0 || shutting_down_i ()) - // Too late. Or, maybe too early. Either fini () has already - // been called, or init () was never called. - return object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1; - - // No mutex here. Only the main thread should destroy the singleton - // ACE_OS_Object_Manager instance. - - // Indicate that the ACE_OS_Object_Manager instance is being shut - // down. This object manager should be the last one to be shut - // down. - object_manager_state_ = OBJ_MAN_SHUTTING_DOWN; - - // If another Object_Manager has registered for termination, do it. - if (next_) - { - next_->fini (); - next_ = 0; // Protect against recursive calls. - } - - // Call all registered cleanup hooks, in reverse order of - // registration. - exit_info_.call_hooks (); - - // Only clean up preallocated objects when the singleton Instance is being - // destroyed. - if (this == instance_) - { - // Close down Winsock (no-op on other platforms). - ACE_OS::socket_fini (); - -#if ! defined (ACE_HAS_STATIC_PREALLOCATION) - // Cleanup the dynamically preallocated objects. -# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) -# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) - if (ACE_OS::thread_mutex_destroy - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK")); -# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ - ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t, - ACE_OS_MONITOR_LOCK) -# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) - if (ACE_OS::recursive_mutex_destroy - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK")); -# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ - ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_CLEANUP_LOCK) -# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) - if (ACE_OS::thread_mutex_destroy - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object [ACE_LOG_MSG_INSTANCE_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK ")); -# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ - ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t, - ACE_LOG_MSG_INSTANCE_LOCK) -# if defined (ACE_HAS_TSS_EMULATION) -# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) - if (ACE_OS::recursive_mutex_destroy - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK")); -# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ - ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_KEY_LOCK) -# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) -# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) - if (ACE_OS::recursive_mutex_destroy - // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. - (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) - ACE_OS_Object_Manager::print_error_message ( - __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK")); -# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ - ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, - ACE_TSS_BASE_LOCK) -# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ -# endif /* ACE_HAS_TSS_EMULATION */ -# if defined (ACE_HAS_WINCE_BROKEN_ERRNO) - ACE_CE_Errno::fini (); -# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */ -# endif /* ACE_MT_SAFE */ -#endif /* ! ACE_HAS_STATIC_PREALLOCATION */ - } - - delete default_mask_; - default_mask_ = 0; - - // Indicate that this ACE_OS_Object_Manager instance has been shut down. - object_manager_state_ = OBJ_MAN_SHUT_DOWN; - - if (dynamically_allocated_) - { - delete this; - } - - if (this == instance_) - instance_ = 0; - - return 0; -} - -int ace_exit_hook_marker = 0; - -int -ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func) -{ - return exit_info_.at_exit_i (&ace_exit_hook_marker, - ACE_reinterpret_cast (ACE_CLEANUP_FUNC, func), - 0); -} - -void -ACE_OS_Object_Manager::print_error_message (u_int line_number, - const ACE_TCHAR *message) -{ - // To avoid duplication of these const strings in OS.o. -#if !defined (ACE_HAS_WINCE) - fprintf (stderr, "ace/OS.cpp, line %u: %s ", - line_number, - message); - perror ("failed"); -#else - // @@ Need to use the following information. - ACE_UNUSED_ARG (line_number); - ACE_UNUSED_ARG (message); - - ACE_TCHAR *lpMsgBuf = 0; - ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - ::GetLastError (), - MAKELANGID (LANG_NEUTRAL, - SUBLANG_DEFAULT), - // Default language - (ACE_TCHAR *) &lpMsgBuf, - 0, - NULL); - ::MessageBox (NULL, - lpMsgBuf, - ACE_LIB_TEXT ("ACE_OS error"), - MB_OK); -#endif -} - -int -ACE_OS_Object_Manager::starting_up (void) -{ - return ACE_OS_Object_Manager::instance_ - ? instance_->starting_up_i () - : 1; -} - -int -ACE_OS_Object_Manager::shutting_down (void) -{ - return ACE_OS_Object_Manager::instance_ - ? instance_->shutting_down_i () - : 1; -} - -#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) -class ACE_OS_Object_Manager_Manager - // = TITLE - // Ensure that the <ACE_OS_Object_Manager> gets initialized at - // program startup, and destroyed at program termination. - // - // = DESCRIPTION - // Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this - // class is created. Therefore, it gets created before main () - // is called. And it gets destroyed after main () returns. -{ -public: - ACE_OS_Object_Manager_Manager (void); - ~ACE_OS_Object_Manager_Manager (void); - -private: - ACE_thread_t saved_main_thread_id_; - // Save the main thread ID, so that destruction can be suppressed. -}; - -ACE_OS_Object_Manager_Manager::ACE_OS_Object_Manager_Manager (void) - : saved_main_thread_id_ (ACE_OS::thr_self ()) -{ - // Ensure that the Object_Manager gets initialized before any - // application threads have been spawned. Because this will be called - // during construction of static objects, that should always be the - // case. - (void) ACE_OS_Object_Manager::instance (); -} - -ACE_OS_Object_Manager_Manager::~ACE_OS_Object_Manager_Manager (void) -{ - if (ACE_OS::thr_equal (ACE_OS::thr_self (), - saved_main_thread_id_)) - { - delete ACE_OS_Object_Manager::instance_; - ACE_OS_Object_Manager::instance_ = 0; - } - // else if this destructor is not called by the main thread, then do - // not delete the ACE_OS_Object_Manager. That causes problems, on - // WIN32 at least. -} - -static ACE_OS_Object_Manager_Manager ACE_OS_Object_Manager_Manager_instance; -#endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */ - #if defined (ACE_HAS_WINCE) ACE_CE_ARGV::ACE_CE_ARGV(ACE_TCHAR* cmdLine) : ce_argv_(0) @@ -23,6 +23,10 @@ # pragma once # endif /* ACE_LACKS_PRAGMA_ONCE */ + +//#include "ace/Object_Manager_Base.h" + + // new ace includes // these are listed in alphabetical order to make it easy to scan over them. // they take care of their own dependancies. @@ -154,10 +158,6 @@ struct ifafilt; # include /**/ <alloca.h> # endif /* ACE_HAS_ALLOCA_H */ - - - - // Create some useful typedefs. # if defined (ACE_HAS_CHARPTR_DL) @@ -168,128 +168,6 @@ typedef const ACE_TCHAR * ACE_DL_TYPE; - - - - - - - - - - - - - - - -////////////////////////////////////////////////////////// -// This is used by Object Manager and classes scheduled for -// cleanup. So you have to see both to use it (i.e. all singletons) - -// Signature for registering a cleanup function that is used by the -// <ACE_Object_Manager> and the <ACE_Thread_Manager>. -# if defined (ACE_HAS_SIG_C_FUNC) -extern "C" { -# endif /* ACE_HAS_SIG_C_FUNC */ -typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */; -# if defined (ACE_HAS_SIG_C_FUNC) -} -# endif /* ACE_HAS_SIG_C_FUNC */ - -/** - * @class ACE_Cleanup - * - * @brief Base class for objects that are cleaned by ACE_Object_Manager. - */ -class ACE_OS_Export ACE_Cleanup -{ -public: - /// No-op constructor. - ACE_Cleanup (void); - - /// Destructor. - virtual ~ACE_Cleanup (void); - - /// Cleanup method that, by default, simply deletes itself. - virtual void cleanup (void *param = 0); -}; - -// Adapter for cleanup, used by ACE_Object_Manager. -extern "C" ACE_OS_Export -void ace_cleanup_destroyer (ACE_Cleanup *, void *param = 0); - -/** - * @class ACE_Cleanup_Info - * - * @brief Hold cleanup information for thread/process - */ -class ACE_OS_Export ACE_Cleanup_Info -{ -public: - /// Default constructor. - ACE_Cleanup_Info (void); - - /// Equality operator. - int operator== (const ACE_Cleanup_Info &o) const; - - /// Inequality operator. - int operator!= (const ACE_Cleanup_Info &o) const; - - /// Point to object that gets passed into the <cleanup_hook_>. - void *object_; - - /// Cleanup hook that gets called back. - ACE_CLEANUP_FUNC cleanup_hook_; - - /// Parameter passed to the <cleanup_hook_>. - void *param_; -}; - -class ACE_Cleanup_Info_Node; - -/** - * @class ACE_OS_Exit_Info - * - * @brief Hold Object Manager cleanup (exit) information. - * - * For internal use by the ACE library, only. - */ -class ACE_OS_Export ACE_OS_Exit_Info -{ -public: - /// Default constructor. - ACE_OS_Exit_Info (void); - - /// Destructor. - ~ACE_OS_Exit_Info (void); - - /// Use to register a cleanup hook. - int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); - - /// Look for a registered cleanup hook object. Returns 1 if already - /// registered, 0 if not. - int find (void *object); - - /// Call all registered cleanup hooks, in reverse order of - /// registration. - void call_hooks (); - -private: - /** - * Keeps track of all registered objects. The last node is only - * used to terminate the list (it doesn't contain a valid - * ACE_Cleanup_Info). - */ - ACE_Cleanup_Info_Node *registered_objects_; -}; -////////////////////////////////////////////////////////////////// - - - - - - ///////////////////////////////////////// // file stuff @@ -306,10 +184,6 @@ private: /////////////////////////////////////////////// - - - - // and where should this go? only used in ACE_OS::bsearch() // We need this for MVS... extern "C" { @@ -317,9 +191,6 @@ extern "C" { } - - - /////////////////////////////////////////////////////////////////// // Don't know where to put these, but since they are only used in OS.i, // they can stay here for now. @@ -399,10 +270,6 @@ inline char *ace_cuserid(char *user) # endif /* !ACE_LACKS_CUSERID && !ACE_HAS_ALT_CUSERID && ... */ - - - - /////////////////////////////////////////////////////////////// // Don't think this is needed (the ifdef that is...) //# if !defined (ACE_HAS_WINCE) @@ -1885,23 +1752,6 @@ private: //////////////////////////////////////////////////////////////////////////// - - - - - - - - - - - - - - - - - ///////////////////////////////////////////////////////////////////////// // These need to be moved out... @@ -1914,238 +1764,6 @@ int ACE_SEH_Default_Exception_Handler (void *); # endif /* ACE_WIN32 */ -/** - * @class ACE_Object_Manager_Base - * - * @brief Base class for ACE_Object_Manager(s). - * - * Encapsulates the most useful ACE_Object_Manager data structures. - */ -class ACE_OS_Export ACE_Object_Manager_Base -{ -# if (defined (ACE_PSOS) && defined (__DIAB)) || \ - (defined (__DECCXX_VER) && __DECCXX_VER < 60000000) - // The Diab compiler got confused and complained about access rights - // if this section was protected (changing this to public makes it happy). - // Similarly, DEC CXX 5.6 needs the methods to be public. -public: -# else /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */ -protected: -# endif /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */ - /// Default constructor. - ACE_Object_Manager_Base (void); - - /// Destructor. - virtual ~ACE_Object_Manager_Base (void); - -public: - /** - * Explicitly initialize. Returns 0 on success, -1 on failure due - * to dynamic allocation failure (in which case errno is set to - * ENOMEM), or 1 if it had already been called. - */ - virtual int init (void) = 0; - - /** - * Explicitly destroy. Returns 0 on success, -1 on failure because - * the number of fini () calls hasn't reached the number of init () - * calls, or 1 if it had already been called. - */ - virtual int fini (void) = 0; - - enum Object_Manager_State - { - OBJ_MAN_UNINITIALIZED = 0, - OBJ_MAN_INITIALIZING, - OBJ_MAN_INITIALIZED, - OBJ_MAN_SHUTTING_DOWN, - OBJ_MAN_SHUT_DOWN - }; - -protected: - /** - * Returns 1 before ACE_Object_Manager_Base 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.) - */ - int starting_up_i (void); - - /** - * Returns 1 after ACE_Object_Manager_Base 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.) - */ - int shutting_down_i (void); - - /// State of the Object_Manager; - Object_Manager_State object_manager_state_; - - /** - * Flag indicating whether the ACE_Object_Manager was dynamically - * allocated by ACE. (If is was dynamically allocated by the - * application, then the application is responsible for destroying - * it.) - */ - u_int dynamically_allocated_; - - /// Link to next Object_Manager, for chaining. - ACE_Object_Manager_Base *next_; -private: - // Disallow copying by not implementing the following . . . - ACE_Object_Manager_Base (const ACE_Object_Manager_Base &); - ACE_Object_Manager_Base &operator= (const ACE_Object_Manager_Base &); -}; - -extern "C" -void -ACE_OS_Object_Manager_Internal_Exit_Hook (void); - - -// @@ This forward declaration should go away. -class ACE_Log_Msg; - -class ACE_OS_Export ACE_OS_Object_Manager : public ACE_Object_Manager_Base -{ -public: - /// Explicitly initialize. - virtual int init (void); - - /// Explicitly destroy. - virtual int fini (void); - - /** - * Returns 1 before the <ACE_OS_Object_Manager> has been - * constructed. See <ACE_Object_Manager::starting_up> for more - * information. - */ - static int starting_up (void); - - /// Returns 1 after the <ACE_OS_Object_Manager> has been destroyed. - /// See <ACE_Object_Manager::shutting_down> for more information. - static int shutting_down (void); - - /// Unique identifiers for preallocated objects. - enum Preallocated_Object - { -# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_OS_MONITOR_LOCK, - ACE_TSS_CLEANUP_LOCK, - ACE_LOG_MSG_INSTANCE_LOCK, -# if defined (ACE_HAS_TSS_EMULATION) - ACE_TSS_KEY_LOCK, -# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) - ACE_TSS_BASE_LOCK, -# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ -# endif /* ACE_HAS_TSS_EMULATION */ -# else - // Without ACE_MT_SAFE, There are no preallocated objects. Make - // sure that the preallocated_array size is at least one by - // declaring this dummy . . . - ACE_OS_EMPTY_PREALLOCATED_OBJECT, -# endif /* ACE_MT_SAFE */ - - /// This enum value must be last! - ACE_OS_PREALLOCATED_OBJECTS - }; - - /// Accesses a default signal set used, for example, in - /// <ACE_Sig_Guard> methods. - static sigset_t *default_mask (void); - - /// Returns the current thread hook for the process. - static ACE_Thread_Hook *thread_hook (void); - - /// Returns the existing thread hook and assign a <new_thread_hook>. - static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *new_thread_hook); - -# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) - /// Get/Set TSS exception action. - static ACE_SEH_EXCEPT_HANDLER seh_except_selector (void); - static ACE_SEH_EXCEPT_HANDLER seh_except_selector (ACE_SEH_EXCEPT_HANDLER); - - static ACE_SEH_EXCEPT_HANDLER seh_except_handler (void); - static ACE_SEH_EXCEPT_HANDLER seh_except_handler (ACE_SEH_EXCEPT_HANDLER); -# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ - -public: - // = Applications shouldn't use these so they're hidden here. - - // They're public so that the <ACE_Object_Manager> can be - // constructed/destructed in <main> with - // <ACE_HAS_NONSTATIC_OBJECT_MANAGER>. - /// Constructor. - ACE_OS_Object_Manager (void); - - /// Destructor. - ~ACE_OS_Object_Manager (void); - -private: - /// Accessor to singleton instance. - static ACE_OS_Object_Manager *instance (void); - - /// Singleton instance pointer. - static ACE_OS_Object_Manager *instance_; - - /// Table of preallocated objects. - static void *preallocated_object[ACE_OS_PREALLOCATED_OBJECTS]; - - /// Default signal set used, for example, in ACE_Sig_Guard. - sigset_t *default_mask_; - - /// Thread hook that's used by this process. - ACE_Thread_Hook *thread_hook_; - - /// For at_exit support. - ACE_OS_Exit_Info exit_info_; - -# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) - /// These handlers determine how a thread handles win32 structured - /// exception. - ACE_SEH_EXCEPT_HANDLER seh_except_selector_; - ACE_SEH_EXCEPT_HANDLER seh_except_handler_; -# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ - - /// For <ACE_OS::atexit> support. - int at_exit (ACE_EXIT_HOOK func); - - /// For use by init () and fini (), to consolidate error reporting. - static void print_error_message (u_int line_number, const ACE_TCHAR *message); - - /// This class is for internal use by ACE_OS, etc., only. - friend class ACE_OS; - friend class ACE_Object_Manager; - friend class ACE_OS_Object_Manager_Manager; - friend class ACE_TSS_Cleanup; - friend class ACE_TSS_Emulation; - friend class ACE_Log_Msg; - friend void ACE_OS_Object_Manager_Internal_Exit_Hook (); -}; -//////////////////////////////////////////////////////////////////////////////// - - - - - - - - - - - - - - - - - - - ////////////////////////////////////////////////////////////////////////// @@ -2397,8 +2015,6 @@ private: ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// // This is only used in OS.i and OS.cpp right now. // Support non-scalar thread keys, such as with some POSIX @@ -2414,8 +2030,6 @@ private: ///////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// // These seem to be used only in OS.i and Timer_Queue_Adapters.cpp # if defined (ACE_HAS_THR_C_FUNC) @@ -2438,9 +2052,9 @@ extern "C" ACE_OS_Export void ace_mutex_lock_cleanup_adapter (void *args); /////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////// // These don't seem to be used anywhere... +#if 0 # if !defined (ACE_DEFAULT_MUTEX_A) # define ACE_DEFAULT_MUTEX_A "ACE_MUTEX" # endif /* ACE_DEFAULT_MUTEX_A */ @@ -2450,23 +2064,15 @@ extern "C" ACE_OS_Export void ace_mutex_lock_cleanup_adapter (void *args); # endif /* ACE_HAS_WCHAR */ # define ACE_DEFAULT_MUTEX ACE_LIB_TEXT (ACE_DEFAULT_MUTEX_A) +#endif /* 0 */ ////////////////////////////////////////////////////////////////////////////// - - - // Need to look into getting rid of this--or moving it to a move apropriate place. # if !defined (ACE_HAS_MINIMAL_ACE_OS) # include "ace/Trace.h" # endif /* ! ACE_HAS_MINIMAL_ACE_OS */ - - - - - - /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // From here down should be stable. @@ -7,6 +7,7 @@ # include "ace/ace_sys_shm.h" # include "ace/ace_sys_uio.h" # include "ace/ace_string.h" +#include "ace/Object_Manager_Base.h" #if defined (__CYGWIN32__) # include /**/ <getopt.h> @@ -10473,11 +10474,6 @@ fileno (FILE *fp) } # endif /* defined (ACE_PSOS) */ -ACE_INLINE -ACE_Cleanup::ACE_Cleanup (void) -{ -} - ACE_INLINE void * ACE_OS::bsearch (const void *key, const void *base, diff --git a/ace/OS_Thread_Adapter.cpp b/ace/OS_Thread_Adapter.cpp index 9d52410ee59..fd8ab1bdac7 100644 --- a/ace/OS_Thread_Adapter.cpp +++ b/ace/OS_Thread_Adapter.cpp @@ -12,6 +12,7 @@ ACE_RCSID (ace, #include "ace/Thread_Hook.h" #include "ace/OS.h" // for thr_self(), etc... +#include "ace/Object_Manager_Base.h" ACE_OS_Thread_Adapter::ACE_OS_Thread_Adapter ( ACE_THR_FUNC user_func diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h index 6ce1bd6cb2d..2f23d1c2643 100644 --- a/ace/Object_Manager.h +++ b/ace/Object_Manager.h @@ -16,7 +16,9 @@ #define ACE_OBJECT_MANAGER_H #include "ace/pre.h" -#include "ace/OS.h" //for ACE_Object_Manager_Base, etc... +//#include "ace/OS.h" //for ACE_Object_Manager_Base, etc... + +#include "ace/Object_Manager_Base.h" #include "ace/Service_Object.h" #include "ace/ACE_export.h" diff --git a/ace/Object_Manager_Base.cpp b/ace/Object_Manager_Base.cpp new file mode 100644 index 00000000000..784a9c0f182 --- /dev/null +++ b/ace/Object_Manager_Base.cpp @@ -0,0 +1,643 @@ +// $Id$ + +#include "ace/Object_Manager_Base.h" + +#include "ace/OS_Errno.h" +#include "ace/ace_threads.h" +#include "ace/OS.h" + + +ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0; + +ACE_Cleanup_Info::ACE_Cleanup_Info (void) + : object_ (0), + cleanup_hook_ (0), + param_ (0) +{ +} + +int +ACE_Cleanup_Info::operator== (const ACE_Cleanup_Info &o) const +{ + return o.object_ == this->object_ + && o.cleanup_hook_ == this->cleanup_hook_ + && o.param_ == this->param_; +} + +int +ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const +{ + return !(*this == o); +} + +class ACE_Cleanup_Info_Node +{ + // = TITLE + // For maintaining a list of ACE_Cleanup_Info items. + // + // = DESCRIPTION + // For internal use by ACE_Object_Manager. +public: + ACE_Cleanup_Info_Node (void); + ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, + ACE_Cleanup_Info_Node *next); + ~ACE_Cleanup_Info_Node (void); + ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &); +private: + ACE_Cleanup_Info cleanup_info_; + ACE_Cleanup_Info_Node *next_; + + friend class ACE_OS_Exit_Info; +}; + +ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void) + : cleanup_info_ (), + next_ (0) +{ +} + +ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info, + ACE_Cleanup_Info_Node *next) + : cleanup_info_ (new_info), + next_ (next) +{ +} + +ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void) +{ + delete next_; +} + +ACE_Cleanup_Info_Node * +ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info) +{ + ACE_Cleanup_Info_Node *new_node; + + ACE_NEW_RETURN (new_node, + ACE_Cleanup_Info_Node (new_info, this), + 0); + + return new_node; +} + +ACE_OS_Exit_Info::ACE_OS_Exit_Info (void) +{ + ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node); +} + +ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void) +{ + delete registered_objects_; + registered_objects_ = 0; +} + +int +ACE_OS_Exit_Info::at_exit_i (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + ACE_Cleanup_Info new_info; + new_info.object_ = object; + new_info.cleanup_hook_ = cleanup_hook; + new_info.param_ = param; + + // Return -1 and sets errno if unable to allocate storage. Enqueue + // at the head and dequeue from the head to get LIFO ordering. + + ACE_Cleanup_Info_Node *new_node; + + if ((new_node = registered_objects_->insert (new_info)) == 0) + return -1; + else + { + registered_objects_ = new_node; + return 0; + } +} + +int +ACE_OS_Exit_Info::find (void *object) +{ + // Check for already in queue, and return 1 if so. + for (ACE_Cleanup_Info_Node *iter = registered_objects_; + iter && iter->next_ != 0; + iter = iter->next_) + { + if (iter->cleanup_info_.object_ == object) + { + // The object has already been registered. + return 1; + } + } + + return 0; +} + +void +ACE_OS_Exit_Info::call_hooks () +{ + // Call all registered cleanup hooks, in reverse order of + // registration. + for (ACE_Cleanup_Info_Node *iter = registered_objects_; + iter && iter->next_ != 0; + iter = iter->next_) + { + ACE_Cleanup_Info &info = iter->cleanup_info_; + if (info.cleanup_hook_ == ACE_reinterpret_cast (ACE_CLEANUP_FUNC, + ace_cleanup_destroyer)) + // The object is an ACE_Cleanup. + ace_cleanup_destroyer (ACE_reinterpret_cast (ACE_Cleanup *, + info.object_), + info.param_); + else if (info.object_ == &ace_exit_hook_marker) + // The hook is an ACE_EXIT_HOOK. + (* ACE_reinterpret_cast (ACE_EXIT_HOOK, info.cleanup_hook_)) (); + else + (*info.cleanup_hook_) (info.object_, info.param_); + } +} + +extern "C" void +ace_cleanup_destroyer (ACE_Cleanup *object, void *param) +{ + object->cleanup (param); +} + +void +ACE_Cleanup::cleanup (void *) +{ + delete this; +} + +//ACE_INLINE +ACE_Cleanup::ACE_Cleanup (void) +{ +} + +ACE_Cleanup::~ACE_Cleanup (void) +{ +} + +#define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\ + {\ + TYPE *obj_p = 0;\ + ACE_NEW_RETURN (obj_p, TYPE, -1);\ + preallocated_object[ID] = (void *) obj_p;\ + } +#define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\ + delete (TYPE *) preallocated_object[ID];\ + preallocated_object[ID] = 0; + +ACE_Object_Manager_Base::ACE_Object_Manager_Base (void) + : object_manager_state_ (OBJ_MAN_UNINITIALIZED) + , dynamically_allocated_ (0) + , next_ (0) +{ +} + +ACE_Object_Manager_Base::~ACE_Object_Manager_Base (void) +{ +#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) + // Clear the flag so that fini () doesn't delete again. + dynamically_allocated_ = 0; +#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ +} + +int +ACE_Object_Manager_Base::starting_up_i () +{ + return object_manager_state_ < OBJ_MAN_INITIALIZED; +} + +int +ACE_Object_Manager_Base::shutting_down_i () +{ + return object_manager_state_ > OBJ_MAN_INITIALIZED; +} + +extern "C" +void +ACE_OS_Object_Manager_Internal_Exit_Hook (void) +{ + if (ACE_OS_Object_Manager::instance_) + ACE_OS_Object_Manager::instance ()->fini (); +} + +ACE_OS_Object_Manager *ACE_OS_Object_Manager::instance_ = 0; + +void *ACE_OS_Object_Manager::preallocated_object[ + ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS] = { 0 }; + +ACE_OS_Object_Manager::ACE_OS_Object_Manager (void) + // default_mask_ isn't initialized, because it's defined by <init>. + : thread_hook_ (0) + , exit_info_ () +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + , seh_except_selector_ (ACE_SEH_Default_Exception_Selector) + , seh_except_handler_ (ACE_SEH_Default_Exception_Handler) +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ +{ + // If instance_ was not 0, then another ACE_OS_Object_Manager has + // already been instantiated (it is likely to be one initialized by + // way of library/DLL loading). Let this one go through + // construction in case there really is a good reason for it (like, + // ACE is a static/archive library, and this one is the non-static + // instance (with ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has + // a good reason for creating a separate one) but the original one + // will be the one retrieved from calls to + // ACE_Object_Manager::instance(). + + // Be sure that no further instances are created via instance (). + if (instance_ == 0) + instance_ = this; + + init (); +} + +ACE_OS_Object_Manager::~ACE_OS_Object_Manager (void) +{ + dynamically_allocated_ = 0; // Don't delete this again in fini() + fini (); +} + +sigset_t * +ACE_OS_Object_Manager::default_mask (void) +{ + return ACE_OS_Object_Manager::instance ()->default_mask_; +} + +ACE_Thread_Hook * +ACE_OS_Object_Manager::thread_hook (void) +{ + return ACE_OS_Object_Manager::instance ()->thread_hook_; +} + +#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) +ACE_SEH_EXCEPT_HANDLER +ACE_OS_Object_Manager::seh_except_selector (void) +{ + return ACE_OS_Object_Manager::instance ()->seh_except_selector_; +} + +ACE_SEH_EXCEPT_HANDLER +ACE_OS_Object_Manager::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n) +{ + ACE_OS_Object_Manager *instance = + ACE_OS_Object_Manager::instance (); + + ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_selector_; + instance->seh_except_selector_ = n; + return retv; +} + +ACE_SEH_EXCEPT_HANDLER +ACE_OS_Object_Manager::seh_except_handler (void) +{ + return ACE_OS_Object_Manager::instance ()->seh_except_handler_; +} + +ACE_SEH_EXCEPT_HANDLER +ACE_OS_Object_Manager::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n) +{ + ACE_OS_Object_Manager *instance = + ACE_OS_Object_Manager::instance (); + + ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_handler_; + instance->seh_except_handler_ = n; + return retv; +} +#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + +ACE_Thread_Hook * +ACE_OS_Object_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook) +{ + ACE_OS_Object_Manager *os_om = ACE_OS_Object_Manager::instance (); + ACE_Thread_Hook *old_hook = os_om->thread_hook_; + os_om->thread_hook_ = new_thread_hook; + return old_hook; +} + +ACE_OS_Object_Manager * +ACE_OS_Object_Manager::instance (void) +{ + // This function should be called during construction of static + // instances, or before any other threads have been created in the + // process. So, it's not thread safe. + + if (instance_ == 0) + { + ACE_OS_Object_Manager *instance_pointer; + + ACE_NEW_RETURN (instance_pointer, + ACE_OS_Object_Manager, + 0); + // I (coryan) removed it, using asserts in the OS layer + // brings down the Log msg stuff + // ACE_ASSERT (instance_pointer == instance_); + + instance_pointer->dynamically_allocated_ = 1; + + } + + return instance_; +} + +int +ACE_OS_Object_Manager::init (void) +{ + if (starting_up_i ()) + { + // First, indicate that this ACE_OS_Object_Manager instance is being + // initialized. + object_manager_state_ = OBJ_MAN_INITIALIZING; + + if (this == instance_) + { +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# if defined (ACE_HAS_WINCE_BROKEN_ERRNO) + ACE_CE_Errno::init (); +# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */ + ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK) + if (ACE_OS::thread_mutex_init + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK")); + ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_CLEANUP_LOCK) + if (ACE_OS::recursive_mutex_init + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK")); + ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, + ACE_LOG_MSG_INSTANCE_LOCK) + if (ACE_OS::thread_mutex_init + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_LOG_MSG_INSTANCE_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK")); +# if defined (ACE_HAS_TSS_EMULATION) + ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_KEY_LOCK) + if (ACE_OS::recursive_mutex_init + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK")); +# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) + ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_BASE_LOCK) + if (ACE_OS::recursive_mutex_init + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK")); +# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# endif /* ACE_HAS_TSS_EMULATION */ +#endif /* ACE_MT_SAFE */ + + // Open Winsock (no-op on other platforms). + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + // Register the exit hook, for use by ACE_OS::exit (). + ACE_OS::set_exit_hook (&ACE_OS_Object_Manager_Internal_Exit_Hook); + } + + ACE_NEW_RETURN (default_mask_, sigset_t, -1); + ACE_OS::sigfillset (default_mask_); + + // Finally, indicate that the ACE_OS_Object_Manager instance has + // been initialized. + object_manager_state_ = OBJ_MAN_INITIALIZED; + +#if defined (ACE_WIN32) + ACE_OS::win32_versioninfo_.dwOSVersionInfoSize = + sizeof (OSVERSIONINFO); + ::GetVersionEx (&ACE_OS::win32_versioninfo_); +#endif /* ACE_WIN32 */ + return 0; + } else { + // Had already initialized. + return 1; + } +} + +// Clean up an ACE_OS_Object_Manager. There can be instances of this object +// other than The Instance. This can happen if a user creates one for some +// reason. All objects clean up their per-object information and managed +// objects, but only The Instance cleans up the static preallocated objects. +int +ACE_OS_Object_Manager::fini (void) +{ + if (instance_ == 0 || shutting_down_i ()) + // Too late. Or, maybe too early. Either fini () has already + // been called, or init () was never called. + return object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1; + + // No mutex here. Only the main thread should destroy the singleton + // ACE_OS_Object_Manager instance. + + // Indicate that the ACE_OS_Object_Manager instance is being shut + // down. This object manager should be the last one to be shut + // down. + object_manager_state_ = OBJ_MAN_SHUTTING_DOWN; + + // If another Object_Manager has registered for termination, do it. + if (next_) + { + next_->fini (); + next_ = 0; // Protect against recursive calls. + } + + // Call all registered cleanup hooks, in reverse order of + // registration. + exit_info_.call_hooks (); + + // Only clean up preallocated objects when the singleton Instance is being + // destroyed. + if (this == instance_) + { + // Close down Winsock (no-op on other platforms). + ACE_OS::socket_fini (); + +#if ! defined (ACE_HAS_STATIC_PREALLOCATION) + // Cleanup the dynamically preallocated objects. +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) + if (ACE_OS::thread_mutex_destroy + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK")); +# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t, + ACE_OS_MONITOR_LOCK) +# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) + if (ACE_OS::recursive_mutex_destroy + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK")); +# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_CLEANUP_LOCK) +# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) + if (ACE_OS::thread_mutex_destroy + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object [ACE_LOG_MSG_INSTANCE_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK ")); +# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t, + ACE_LOG_MSG_INSTANCE_LOCK) +# if defined (ACE_HAS_TSS_EMULATION) +# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) + if (ACE_OS::recursive_mutex_destroy + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK")); +# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_KEY_LOCK) +# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) +# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK) + if (ACE_OS::recursive_mutex_destroy + // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor. + (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) + ACE_OS_Object_Manager::print_error_message ( + __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK")); +# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */ + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_BASE_LOCK) +# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# endif /* ACE_HAS_TSS_EMULATION */ +# if defined (ACE_HAS_WINCE_BROKEN_ERRNO) + ACE_CE_Errno::fini (); +# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */ +# endif /* ACE_MT_SAFE */ +#endif /* ! ACE_HAS_STATIC_PREALLOCATION */ + } + + delete default_mask_; + default_mask_ = 0; + + // Indicate that this ACE_OS_Object_Manager instance has been shut down. + object_manager_state_ = OBJ_MAN_SHUT_DOWN; + + if (dynamically_allocated_) + { + delete this; + } + + if (this == instance_) + instance_ = 0; + + return 0; +} + +int ace_exit_hook_marker = 0; + +int +ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func) +{ + return exit_info_.at_exit_i (&ace_exit_hook_marker, + ACE_reinterpret_cast (ACE_CLEANUP_FUNC, func), + 0); +} + +void +ACE_OS_Object_Manager::print_error_message (u_int line_number, + const ACE_TCHAR *message) +{ + // To avoid duplication of these const strings in OS.o. +#if !defined (ACE_HAS_WINCE) + fprintf (stderr, "ace/OS.cpp, line %u: %s ", + line_number, + message); + perror ("failed"); +#else + // @@ Need to use the following information. + ACE_UNUSED_ARG (line_number); + ACE_UNUSED_ARG (message); + + ACE_TCHAR *lpMsgBuf = 0; + ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + ::GetLastError (), + MAKELANGID (LANG_NEUTRAL, + SUBLANG_DEFAULT), + // Default language + (ACE_TCHAR *) &lpMsgBuf, + 0, + NULL); + ::MessageBox (NULL, + lpMsgBuf, + ACE_LIB_TEXT ("ACE_OS error"), + MB_OK); +#endif +} + +int +ACE_OS_Object_Manager::starting_up (void) +{ + return ACE_OS_Object_Manager::instance_ + ? instance_->starting_up_i () + : 1; +} + +int +ACE_OS_Object_Manager::shutting_down (void) +{ + return ACE_OS_Object_Manager::instance_ + ? instance_->shutting_down_i () + : 1; +} + +#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) +class ACE_OS_Object_Manager_Manager + // = TITLE + // Ensure that the <ACE_OS_Object_Manager> gets initialized at + // program startup, and destroyed at program termination. + // + // = DESCRIPTION + // Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this + // class is created. Therefore, it gets created before main () + // is called. And it gets destroyed after main () returns. +{ +public: + ACE_OS_Object_Manager_Manager (void); + ~ACE_OS_Object_Manager_Manager (void); + +private: + ACE_thread_t saved_main_thread_id_; + // Save the main thread ID, so that destruction can be suppressed. +}; + +ACE_OS_Object_Manager_Manager::ACE_OS_Object_Manager_Manager (void) + : saved_main_thread_id_ (ACE_OS::thr_self ()) +{ + // Ensure that the Object_Manager gets initialized before any + // application threads have been spawned. Because this will be called + // during construction of static objects, that should always be the + // case. + (void) ACE_OS_Object_Manager::instance (); +} + +ACE_OS_Object_Manager_Manager::~ACE_OS_Object_Manager_Manager (void) +{ + if (ACE_OS::thr_equal (ACE_OS::thr_self (), + saved_main_thread_id_)) + { + delete ACE_OS_Object_Manager::instance_; + ACE_OS_Object_Manager::instance_ = 0; + } + // else if this destructor is not called by the main thread, then do + // not delete the ACE_OS_Object_Manager. That causes problems, on + // WIN32 at least. +} + +static ACE_OS_Object_Manager_Manager ACE_OS_Object_Manager_Manager_instance; +#endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */ diff --git a/ace/Object_Manager_Base.h b/ace/Object_Manager_Base.h new file mode 100644 index 00000000000..b678e5a4f81 --- /dev/null +++ b/ace/Object_Manager_Base.h @@ -0,0 +1,362 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Object_Manager_Base.h + * + * $Id$ + * + * @author David L. Levine <levine@cs.wustl.edu> + * @author Matthias Kerkhoff + * @author and Per Andersson + */ +//============================================================================= + +#ifndef ACE_OBJECT_MANAGER_BASE_H +#define ACE_OBJECT_MANAGER_BASE_H +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ace_sys_types.h" +#include "ace/OS_Export.h" +#include "ace/Global_Macros.h" + +////////////////////////////////////////////////////////// +// This is used by Object Manager and classes scheduled for +// cleanup. So you have to see both to use it (i.e. all singletons) + +// Signature for registering a cleanup function that is used by the +// <ACE_Object_Manager> and the <ACE_Thread_Manager>. +# if defined (ACE_HAS_SIG_C_FUNC) +extern "C" { +# endif /* ACE_HAS_SIG_C_FUNC */ +typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */; +# if defined (ACE_HAS_SIG_C_FUNC) +} +# endif /* ACE_HAS_SIG_C_FUNC */ + +/** + * @class ACE_Cleanup + * + * @brief Base class for objects that are cleaned by ACE_Object_Manager. + */ +class ACE_OS_Export ACE_Cleanup +{ +public: + /// No-op constructor. + ACE_Cleanup (void); + + /// Destructor. + virtual ~ACE_Cleanup (void); + + /// Cleanup method that, by default, simply deletes itself. + virtual void cleanup (void *param = 0); +}; + +// Adapter for cleanup, used by ACE_Object_Manager. +extern "C" ACE_OS_Export +void ace_cleanup_destroyer (ACE_Cleanup *, void *param = 0); + +/** + * @class ACE_Cleanup_Info + * + * @brief Hold cleanup information for thread/process + */ +class ACE_OS_Export ACE_Cleanup_Info +{ +public: + /// Default constructor. + ACE_Cleanup_Info (void); + + /// Equality operator. + int operator== (const ACE_Cleanup_Info &o) const; + + /// Inequality operator. + int operator!= (const ACE_Cleanup_Info &o) const; + + /// Point to object that gets passed into the <cleanup_hook_>. + void *object_; + + /// Cleanup hook that gets called back. + ACE_CLEANUP_FUNC cleanup_hook_; + + /// Parameter passed to the <cleanup_hook_>. + void *param_; +}; + +class ACE_Cleanup_Info_Node; + +/** + * @class ACE_OS_Exit_Info + * + * @brief Hold Object Manager cleanup (exit) information. + * + * For internal use by the ACE library, only. + */ +class ACE_OS_Export ACE_OS_Exit_Info +{ +public: + /// Default constructor. + ACE_OS_Exit_Info (void); + + /// Destructor. + ~ACE_OS_Exit_Info (void); + + /// Use to register a cleanup hook. + int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); + + /// Look for a registered cleanup hook object. Returns 1 if already + /// registered, 0 if not. + int find (void *object); + + /// Call all registered cleanup hooks, in reverse order of + /// registration. + void call_hooks (); + +private: + /** + * Keeps track of all registered objects. The last node is only + * used to terminate the list (it doesn't contain a valid + * ACE_Cleanup_Info). + */ + ACE_Cleanup_Info_Node *registered_objects_; +}; +////////////////////////////////////////////////////////////////// + + + + + +/** + * @class ACE_Object_Manager_Base + * + * @brief Base class for ACE_Object_Manager(s). + * + * Encapsulates the most useful ACE_Object_Manager data structures. + */ +class ACE_OS_Export ACE_Object_Manager_Base +{ +# if (defined (ACE_PSOS) && defined (__DIAB)) || \ + (defined (__DECCXX_VER) && __DECCXX_VER < 60000000) + // The Diab compiler got confused and complained about access rights + // if this section was protected (changing this to public makes it happy). + // Similarly, DEC CXX 5.6 needs the methods to be public. +public: +# else /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */ +protected: +# endif /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */ + /// Default constructor. + ACE_Object_Manager_Base (void); + + /// Destructor. + virtual ~ACE_Object_Manager_Base (void); + +public: + /** + * Explicitly initialize. Returns 0 on success, -1 on failure due + * to dynamic allocation failure (in which case errno is set to + * ENOMEM), or 1 if it had already been called. + */ + virtual int init (void) = 0; + + /** + * Explicitly destroy. Returns 0 on success, -1 on failure because + * the number of fini () calls hasn't reached the number of init () + * calls, or 1 if it had already been called. + */ + virtual int fini (void) = 0; + + enum Object_Manager_State + { + OBJ_MAN_UNINITIALIZED = 0, + OBJ_MAN_INITIALIZING, + OBJ_MAN_INITIALIZED, + OBJ_MAN_SHUTTING_DOWN, + OBJ_MAN_SHUT_DOWN + }; + +protected: + /** + * Returns 1 before ACE_Object_Manager_Base 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.) + */ + int starting_up_i (void); + + /** + * Returns 1 after ACE_Object_Manager_Base 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.) + */ + int shutting_down_i (void); + + /// State of the Object_Manager; + Object_Manager_State object_manager_state_; + + /** + * Flag indicating whether the ACE_Object_Manager was dynamically + * allocated by ACE. (If is was dynamically allocated by the + * application, then the application is responsible for destroying + * it.) + */ + u_int dynamically_allocated_; + + /// Link to next Object_Manager, for chaining. + ACE_Object_Manager_Base *next_; +private: + // Disallow copying by not implementing the following . . . + ACE_Object_Manager_Base (const ACE_Object_Manager_Base &); + ACE_Object_Manager_Base &operator= (const ACE_Object_Manager_Base &); +}; + + +// @@ This forward declaration should go away. +class ACE_Log_Msg; +class ACE_OS; +class ACE_Object_Manager; +class ACE_OS_Object_Manager_Manager; +class ACE_TSS_Cleanup; +class ACE_TSS_Emulation; +class ACE_Log_Msg; +class ACE_Thread_Hook; +//void ACE_OS_Object_Manager_Internal_Exit_Hook (); + +extern "C" +void +ACE_OS_Object_Manager_Internal_Exit_Hook (void); + + + +class ACE_OS_Export ACE_OS_Object_Manager : public ACE_Object_Manager_Base +{ +public: + /// Explicitly initialize. + virtual int init (void); + + /// Explicitly destroy. + virtual int fini (void); + + /** + * Returns 1 before the <ACE_OS_Object_Manager> has been + * constructed. See <ACE_Object_Manager::starting_up> for more + * information. + */ + static int starting_up (void); + + /// Returns 1 after the <ACE_OS_Object_Manager> has been destroyed. + /// See <ACE_Object_Manager::shutting_down> for more information. + static int shutting_down (void); + + /// Unique identifiers for preallocated objects. + enum Preallocated_Object + { +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_OS_MONITOR_LOCK, + ACE_TSS_CLEANUP_LOCK, + ACE_LOG_MSG_INSTANCE_LOCK, +# if defined (ACE_HAS_TSS_EMULATION) + ACE_TSS_KEY_LOCK, +# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) + ACE_TSS_BASE_LOCK, +# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# endif /* ACE_HAS_TSS_EMULATION */ +# else + // Without ACE_MT_SAFE, There are no preallocated objects. Make + // sure that the preallocated_array size is at least one by + // declaring this dummy . . . + ACE_OS_EMPTY_PREALLOCATED_OBJECT, +# endif /* ACE_MT_SAFE */ + + /// This enum value must be last! + ACE_OS_PREALLOCATED_OBJECTS + }; + + /// Accesses a default signal set used, for example, in + /// <ACE_Sig_Guard> methods. + static sigset_t *default_mask (void); + + /// Returns the current thread hook for the process. + static ACE_Thread_Hook *thread_hook (void); + + /// Returns the existing thread hook and assign a <new_thread_hook>. + static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *new_thread_hook); + +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + /// Get/Set TSS exception action. + static ACE_SEH_EXCEPT_HANDLER seh_except_selector (void); + static ACE_SEH_EXCEPT_HANDLER seh_except_selector (ACE_SEH_EXCEPT_HANDLER); + + static ACE_SEH_EXCEPT_HANDLER seh_except_handler (void); + static ACE_SEH_EXCEPT_HANDLER seh_except_handler (ACE_SEH_EXCEPT_HANDLER); +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + +public: + // = Applications shouldn't use these so they're hidden here. + + // They're public so that the <ACE_Object_Manager> can be + // constructed/destructed in <main> with + // <ACE_HAS_NONSTATIC_OBJECT_MANAGER>. + /// Constructor. + ACE_OS_Object_Manager (void); + + /// Destructor. + ~ACE_OS_Object_Manager (void); + +private: + /// Accessor to singleton instance. + static ACE_OS_Object_Manager *instance (void); + + /// Singleton instance pointer. + static ACE_OS_Object_Manager *instance_; + + /// Table of preallocated objects. + static void *preallocated_object[ACE_OS_PREALLOCATED_OBJECTS]; + + /// Default signal set used, for example, in ACE_Sig_Guard. + sigset_t *default_mask_; + + /// Thread hook that's used by this process. + ACE_Thread_Hook *thread_hook_; + + /// For at_exit support. + ACE_OS_Exit_Info exit_info_; + +# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) + /// These handlers determine how a thread handles win32 structured + /// exception. + ACE_SEH_EXCEPT_HANDLER seh_except_selector_; + ACE_SEH_EXCEPT_HANDLER seh_except_handler_; +# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ + + /// For <ACE_OS::atexit> support. + int at_exit (ACE_EXIT_HOOK func); + + /// For use by init () and fini (), to consolidate error reporting. + static void print_error_message (u_int line_number, const ACE_TCHAR *message); + + /// This class is for internal use by ACE_OS, etc., only. + friend class ACE_OS; + friend class ACE_Object_Manager; + friend class ACE_OS_Object_Manager_Manager; + friend class ACE_TSS_Cleanup; + friend class ACE_TSS_Emulation; + friend class ACE_Log_Msg; + friend void ACE_OS_Object_Manager_Internal_Exit_Hook (); +}; +//////////////////////////////////////////////////////////////////////////////// + + + +#include "ace/post.h" +#endif /* ACE_OBJECT_MANAGER_BASE_H */ diff --git a/ace/Signal.i b/ace/Signal.i index e2ca95be130..55a59ffae72 100644 --- a/ace/Signal.i +++ b/ace/Signal.i @@ -1,6 +1,8 @@ /* -*- C++ -*- */ // $Id$ +#include "ace/Object_Manager_Base.h" + ACE_INLINE ACE_Sig_Set::ACE_Sig_Set (sigset_t *ss) // : sigset_ () diff --git a/ace/Singleton.h b/ace/Singleton.h index 783c3394613..6d4ab8b75ad 100644 --- a/ace/Singleton.h +++ b/ace/Singleton.h @@ -27,6 +27,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Object_Manager_Base.h" + /** * @class ACE_Singleton * diff --git a/ace/Thread_Hook.cpp b/ace/Thread_Hook.cpp index 08c37afbaf6..b63eb880b4b 100644 --- a/ace/Thread_Hook.cpp +++ b/ace/Thread_Hook.cpp @@ -1,7 +1,7 @@ // $Id$ #include "ace/Thread_Hook.h" -#include "ace/OS.h" +#include "ace/Object_Manager_Base.h" ACE_RCSID(ace, Thread_Hook, "$Id$") diff --git a/ace/Trace.cpp b/ace/Trace.cpp index 5a0688ee4bd..3705b593b0e 100644 --- a/ace/Trace.cpp +++ b/ace/Trace.cpp @@ -14,7 +14,7 @@ ACE_RCSID (ace, #define ACE_NTRACE 1 #include "ace/Log_Msg.h" -#include "ace/OS.h" +#include "ace/Object_Manager_Base.h" // = Static initialization. |