diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-03-01 19:15:33 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-03-01 19:15:33 +0000 |
commit | 1f75eb70a72bae885c665f3b91b73b13b836b491 (patch) | |
tree | c08cf828dea0abb4d47ebe6f9df3c58468866ce7 /ace | |
parent | 0e81d140a777185bbc875526fc19d68a1dcea83f (diff) | |
download | ATCD-1f75eb70a72bae885c665f3b91b73b13b836b491.tar.gz |
added ACE_OS_Object_Manager
Diffstat (limited to 'ace')
-rw-r--r-- | ace/OS.cpp | 613 | ||||
-rw-r--r-- | ace/OS.h | 181 | ||||
-rw-r--r-- | ace/OS.i | 26 | ||||
-rw-r--r-- | ace/Object_Manager.cpp | 296 | ||||
-rw-r--r-- | ace/Object_Manager.h | 196 |
5 files changed, 894 insertions, 418 deletions
diff --git a/ace/OS.cpp b/ace/OS.cpp index 0f993df9d35..d97bdfbaa0f 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -10,11 +10,9 @@ # include "ace/OS.i" #endif /* ACE_HAS_INLINED_OS_CALLS */ -#include "ace/Synch_T.h" -#include "ace/streams.h" - #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) # include "ace/Containers.h" +# include "ace/Synch_T.h" /* for ACE_TSS */ # if defined (ACE_WIN32) # include "ace/Thread_Manager.h" # endif /* ACE_WIN32 */ @@ -23,8 +21,6 @@ ACE_RCSID(ace, OS, "$Id$") #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) -# include "ace/Object_Manager.h" - # if defined (ACE_HAS_WINCE) const wchar_t *ACE_OS::day_of_week_name[] = {ACE_TEXT ("Sun"), ACE_TEXT ("Mon"), ACE_TEXT ("Tue"), ACE_TEXT ("Wed"), @@ -40,26 +36,179 @@ const wchar_t *ACE_OS::month_name[] = {ACE_TEXT ("Jan"), ACE_TEXT ("Feb"), static const ASYS_TCHAR *ACE_OS_CTIME_R_FMTSTR = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n"); # endif /* ACE_HAS_WINCE */ +class ACE_OS_Thread_Mutex_Guard +{ + // = TITLE + // This data structure is meant to be used within an ACE_OS + // function. It performs automatic aquisition and release of + // an ACE_thread_mutex_t. + // + // = DESCRIPTION + // For internal use only by ACE_OS. +public: + ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m); + // Implicitly and automatically acquire the lock. + + ~ACE_OS_Thread_Mutex_Guard (void); + // Implicitly release the lock. + + int acquire (void); + // Explicitly acquire the lock. + + int release (void); + // Explicitly release the lock. + +protected: + ACE_thread_mutex_t &lock_; + // Reference to the mutex. + + int owner_; + // Keeps track of whether we acquired the lock or failed. + + // = Prevent assignment and initialization. + ACE_OS_Thread_Mutex_Guard &operator= (const ACE_OS_Thread_Mutex_Guard &); + ACE_OS_Thread_Mutex_Guard (const ACE_OS_Thread_Mutex_Guard &); +}; + +inline +int +ACE_OS_Thread_Mutex_Guard::acquire (void) +{ + return owner_ = ACE_OS::thread_mutex_lock (&lock_); +} + +inline +int +ACE_OS_Thread_Mutex_Guard::release (void) +{ + if (owner_ == -1) + return 0; + else + { + owner_ = -1; + return ACE_OS::thread_mutex_unlock (&lock_); + } +} + +inline +ACE_OS_Thread_Mutex_Guard::ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m) + : lock_ (m) +{ + acquire (); +} + +ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard () +{ + release (); +} + +class ACE_OS_Recursive_Thread_Mutex_Guard +{ + // = TITLE + // This data structure is meant to be used within an ACE_OS + // function. It performs automatic aquisition and release of + // an ACE_recursive_thread_mutex_t. + // + // = DESCRIPTION + // For internal use only by ACE_OS. +public: + ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t &m); + // Implicitly and automatically acquire the lock. + + ~ACE_OS_Recursive_Thread_Mutex_Guard (void); + // Implicitly release the lock. + + int acquire (void); + // Explicitly acquire the lock. + + int release (void); + // Explicitly release the lock. + +protected: + ACE_recursive_thread_mutex_t &lock_; + // Reference to the mutex. + + int owner_; + // Keeps track of whether we acquired the lock or failed. + + // = Prevent assignment and initialization. + ACE_OS_Recursive_Thread_Mutex_Guard &operator= ( + const ACE_OS_Recursive_Thread_Mutex_Guard &); + ACE_OS_Recursive_Thread_Mutex_Guard ( + const ACE_OS_Recursive_Thread_Mutex_Guard &); +}; + +inline +int +ACE_OS_Recursive_Thread_Mutex_Guard::acquire (void) +{ + return owner_ = ACE_OS::recursive_mutex_lock (&lock_); +} + +inline +int +ACE_OS_Recursive_Thread_Mutex_Guard::release (void) +{ + if (owner_ == -1) + return 0; + else + { + owner_ = -1; + return ACE_OS::recursive_mutex_unlock (&lock_); + } +} + +inline +ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard ( + ACE_recursive_thread_mutex_t &m) + : lock_ (m) +{ + acquire (); +} + +ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard () +{ + release (); +} + +#define ACE_OS_GUARD \ + ACE_OS_Thread_Mutex_Guard (*(ACE_thread_mutex_t *) \ + ACE_OS_Object_Manager::preallocated_object[ \ + ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]); + +#define ACE_TSS_CLEANUP_GUARD \ + ACE_OS_Recursive_Thread_Mutex_Guard (*(ACE_recursive_thread_mutex_t *) \ + ACE_OS_Object_Manager::preallocated_object[ \ + ACE_OS_Object_Manager::ACE_TSS_CLEANUP_LOCK]); + +#define ACE_TSS_BASE_GUARD \ + ACE_OS_Recursive_Thread_Mutex_Guard (*(ACE_recursive_thread_mutex_t *) \ + ACE_OS_Object_Manager::preallocated_object[ \ + ACE_OS_Object_Manager::ACE_TSS_BASE_LOCK]); + + # if defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) int ACE_OS::netdb_acquire (void) { - ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - return ace_os_monitor_lock->acquire (); + return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t *) + ACE_OS_Object_Manager::preallocated_object[ + ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]); } int ACE_OS::netdb_release (void) { - ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - return ace_os_monitor_lock->release (); + return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t *) + ACE_OS_Object_Manager::preallocated_object[ + ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]); } # endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */ -#endif /* defined (ACE_MT_SAFE) */ +#else /* ! ACE_MT_SAFE */ +# define ACE_OS_GUARD +# define ACE_TSS_CLEANUP_GUARD +# define ACE_TSS_BASE_GUARD +#endif /* ! ACE_MT_SAFE */ ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0; @@ -794,7 +943,7 @@ ACE_OS::gets (char *str, int n) return (c == EOF) ? 0 : str; } -#else +#else /* ACE_HAS_WINCE */ int fprintf (FILE *fp, char *format, const char *msg) { @@ -1500,12 +1649,8 @@ ACE_TSS_Cleanup::exit (void * /* status */) // While holding the lock, we only collect the ACE_TSS_Info objects // in an array without invoking the according destructors. - { - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *lock)); + ACE_TSS_CLEANUP_GUARD // Iterate through all the thread-specific items and free them all // up. @@ -1552,13 +1697,10 @@ ACE_TSS_Cleanup::exit (void * /* status */) } } - // Acquiring ACE_TSS_Cleanup::lock_ to free TLS keys and remove + // Acquire the ACE_TSS_CLEANUP_LOCK, then free TLS keys and remove // entries from ACE_TSS_Info table. { - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *lock)); + ACE_TSS_CLEANUP_GUARD # if 0 // We shouldn't free the key and remove it from the table here @@ -1625,10 +1767,7 @@ ACE_TSS_Cleanup::instance (void) if (ACE_TSS_Cleanup::instance_ == 0) { // Insure that we are serialized! - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock, 0)); + ACE_TSS_CLEANUP_GUARD // Now, use the Double-Checked Locking pattern to make sure we // only create the ACE_TSS_Cleanup instance once. @@ -1647,10 +1786,7 @@ ACE_TSS_Cleanup::insert (ACE_thread_key_t key, void *inst) { // ACE_TRACE ("ACE_TSS_Cleanup::insert"); - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock, -1)); + ACE_TSS_CLEANUP_GUARD ACE_KEY_INDEX (key_index, key); return this->table_.set (ACE_TSS_Info (key, destructor, inst), key_index); @@ -1660,10 +1796,7 @@ int ACE_TSS_Cleanup::remove (ACE_thread_key_t key) { // ACE_TRACE ("ACE_TSS_Cleanup::remove"); - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock, -1)); + ACE_TSS_CLEANUP_GUARD ACE_KEY_INDEX (key_index, key); if (key_index <= this->table_.size ()) @@ -1691,10 +1824,7 @@ ACE_TSS_Cleanup::remove (ACE_thread_key_t key) int ACE_TSS_Cleanup::detach (void *inst) { - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock, -1)); + ACE_TSS_CLEANUP_GUARD ACE_TSS_Info *key_info = 0; int success = 0; @@ -1743,10 +1873,7 @@ ACE_TSS_Cleanup::key_used (ACE_thread_key_t key) // set it and increment the key's thread_count_. if (! in_use_->test_and_set (key)) { - ACE_MT (ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); - ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *lock)); + ACE_TSS_CLEANUP_GUARD // Retrieve the key's ACE_TSS_Info and increment its thread_count_. ACE_KEY_INDEX (key_index, key); @@ -1803,11 +1930,8 @@ ACE_TSS_Emulation::tss_base (void* ts_storage[]) // Create the one native TSS key, if necessary. if (key_created_ == 0) { - ACE_Recursive_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_TSS_BASE_LOCK); - - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock, 0); + // Double-checked lock . . . + ACE_TSS_BASE_GUARD if (key_created_ == 0) { @@ -1943,13 +2067,13 @@ ACE_OS::cleanup_tss (const u_int main_thread) if (main_thread) { -#if ! defined (ACE_HAS_TSS_EMULATION) +#if !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_HAS_MINIMAL_ACE_OS) // Just close the ACE_Log_Msg for the current (which should be // main) thread. We don't have TSS emulation; if there's native // TSS, it should call its destructors when the main thread // exits. ACE_Log_Msg::close (); -#endif /* ! ACE_HAS_TSS_EMULATION */ +#endif /* ! ACE_HAS_TSS_EMULATION && ! ACE_HAS_MINIMAL_ACE_OS */ #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) // Remove all TSS_Info table entries. @@ -1964,7 +2088,8 @@ ACE_OS::cleanup_tss (const u_int main_thread) void ACE_Thread_Adapter::inherit_log_msg (void) { -#if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) +#if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) && \ + !defined (ACE_HAS_MINIMAL_ACE_OS) // Inherit the logging features if the parent thread has an // <ACE_Log_Msg>. Note that all of the following operations occur // within thread-specific storage. @@ -1995,7 +2120,7 @@ ACE_Thread_Adapter::inherit_log_msg (void) // Block the thread from proceeding until // thread manager has thread descriptor ready. -#endif /* ACE_THREADS_DONT_INHERIT_LOG_MSG */ +#endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG && ! ACE_HAS_MINIMAL_ACE_OS */ } void * @@ -2018,10 +2143,12 @@ ACE_Thread_Adapter::invoke (void) // reference. if (this->thr_mgr () != 0) { +# if !defined (ACE_HAS_MINIMAL_ACE_OS) ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance (); // Keep track of the <Thread_Manager> that's associated with this // <exit_hook>. exit_hook.thr_mgr (this->thr_mgr ()); +# endif /* ! ACE_HAS_MINIMAL_ACE_OS */ } # else // Without TSS, create an <ACE_Thread_Exit> instance. When this @@ -2230,7 +2357,8 @@ ACE_Thread_Adapter::ACE_Thread_Adapter (ACE_THR_FUNC user_func, #endif /* ACE_THREADS_DONT_INHERIT_LOG_MSG */ { // ACE_TRACE ("Ace_Thread_Adapter::Ace_Thread_Adapter"); -#if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) +#if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) && \ + !defined (ACE_HAS_MINIMAL_ACE_OS) if (ACE_Log_Msg::exists ()) { ACE_Log_Msg *inherit_log_ = ACE_LOG_MSG; @@ -2244,7 +2372,7 @@ ACE_Thread_Adapter::ACE_Thread_Adapter (ACE_THR_FUNC user_func, this->seh_except_handler_ = handler; # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ } -#endif /* ACE_THREADS_DONT_INHERIT_LOG_MSG */ +#endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG && ! ACE_HAS_MINIMAL_ACE_OS */ } int @@ -3490,6 +3618,26 @@ ACE_OS::thr_key_detach (void *inst) # endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */ } +void +ACE_OS::unique_name (const void *object, + LPTSTR name, + size_t length) +{ + // The process ID will provide uniqueness between processes on the + // same machine. The "this" pointer of the <object> will provide + // uniqueness between other "live" objects in the same process. The + // uniqueness of this name is therefore only valid for the life of + // <object>. + TCHAR temp_name[ACE_UNIQUE_NAME_LEN]; + ACE_OS::sprintf (temp_name, + ACE_TEXT ("%x%d"), + object, + ACE_OS::getpid ()); + ACE_OS::strncpy (name, + temp_name, + length); +} + int ACE_OS::argv_to_string (ASYS_TCHAR **argv, ASYS_TCHAR *&buf, @@ -3538,9 +3686,9 @@ ACE_OS::argv_to_string (ASYS_TCHAR **argv, if (substitute_env_args && (argv[j][0] == '$' && (temp = ACE_OS::getenv (&argv[j][1])) != 0)) - end = ACE::strecpy (end, temp); + end = ACE_OS::strecpy (end, temp); else - end = ACE::strecpy (end, argv[j]); + end = ACE_OS::strecpy (end, argv[j]); // Replace the null char that strecpy put there with white // space. @@ -4082,8 +4230,10 @@ ACE_OS::fork (const char *program_name) ::fork (); #endif /* ACE_HAS_STHREADS */ +#if !defined (ACE_HAS_MINIMAL_ACE_OS) if (pid == 0) ACE_LOG_MSG->sync (program_name); +#endif /* ! ACE_HAS_MINIMAL_ACE_OS */ return pid; # endif /* ACE_WIN32 */ @@ -4186,10 +4336,7 @@ ACE_OS::pread (ACE_HANDLE handle, # if defined (ACE_HAS_P_READ_WRITE) # if defined (ACE_WIN32) - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, -1)); + ACE_OS_GUARD // Remember the original file pointer position DWORD original_position = ::SetFilePointer (handle, @@ -4270,10 +4417,7 @@ ACE_OS::pread (ACE_HANDLE handle, # else /* ACE_HAS_P_READ_WRITE */ - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, -1)); + ACE_OS_GUARD // Remember the original file pointer position off_t original_position = ACE_OS::lseek (handle, @@ -4317,10 +4461,7 @@ ACE_OS::pwrite (ACE_HANDLE handle, # if defined (ACE_HAS_P_READ_WRITE) # if defined (ACE_WIN32) - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, -1)); + ACE_OS_GUARD // Remember the original file pointer position DWORD original_position = ::SetFilePointer (handle, @@ -4399,10 +4540,7 @@ ACE_OS::pwrite (ACE_HANDLE handle, # endif /* ACE_WIN32 */ # else /* ACE_HAS_P_READ_WRITE */ - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, -1)); + ACE_OS_GUARD // Remember the original file pointer position off_t original_position = ACE_OS::lseek (handle, @@ -4488,16 +4626,17 @@ ACE_OS::open (const char *filename, if (ACE_BIT_ENABLED (mode, FILE_FLAG_POSIX_SEMANTICS)) flags |= FILE_FLAG_POSIX_SEMANTICS; - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = 0;) + ACE_MT (ACE_thread_mutex_t *ace_os_monitor_lock = 0;) if (ACE_BIT_ENABLED (mode, _O_APPEND)) { ACE_MT ( - ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ace_os_monitor_lock->acquire (); - ) + ace_os_monitor_lock = (ACE_thread_mutex_t *) + ACE_OS_Object_Manager::preallocated_object[ + ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]; + ACE_OS::thread_mutex_lock (ace_os_monitor_lock); + ) } ACE_HANDLE h = ::CreateFileA (filename, access, @@ -4518,7 +4657,7 @@ ACE_OS::open (const char *filename, ::SetFilePointer (h, 0, 0, FILE_END); } - ACE_MT (ace_os_monitor_lock->release ();) + ACE_MT (ACE_OS::thread_mutex_unlock (ace_os_monitor_lock);) } if (h == ACE_INVALID_HANDLE) @@ -4598,16 +4737,17 @@ ACE_OS::open (const wchar_t *filename, if (ACE_BIT_ENABLED (mode, FILE_FLAG_POSIX_SEMANTICS)) flags |= FILE_FLAG_POSIX_SEMANTICS; - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = 0;) + ACE_MT (ACE_thread_mutex_t *ace_os_monitor_lock = 0;) if (ACE_BIT_ENABLED (mode, _O_APPEND)) { ACE_MT ( - ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ace_os_monitor_lock->acquire (); - ) + ace_os_monitor_lock = (ACE_thread_mutex_t *) + ACE_OS_Object_Manager::preallocated_object[ + ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]; + ACE_OS::thread_mutex_lock (ace_os_monitor_lock); + ) } ACE_HANDLE h = ::CreateFileW (filename, access, @@ -4629,7 +4769,7 @@ ACE_OS::open (const wchar_t *filename, ::SetFilePointer (h, 0, 0, FILE_END); } - ACE_MT (ace_os_monitor_lock->release ();) + ACE_MT (ACE_OS::thread_mutex_unlock (ace_os_monitor_lock);) } if (h == ACE_INVALID_HANDLE) @@ -4825,16 +4965,11 @@ time_t ACE_OS::mktime (struct tm *t) { // ACE_TRACE ("ACE_OS::asctime"); -# if defined (ACE_HAS_MT_SAFE_MKTIME) || !defined (ACE_HAS_THREADS) - ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1); -# else - ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object - (ACE_Object_Manager::ACE_OS_MONITOR_LOCK); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, (time_t) -1)); +# if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME) + ACE_OS_GUARD +# endif /* ACE_HAS_THREADS && ! ACE_HAS_MT_SAFE_MKTIME */ ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1); -# endif /* ACE_HAS_MT_SAFE_MKTIME */ } # endif /* !ACE_HAS_WINCE */ @@ -4858,18 +4993,18 @@ ACE_OS::rwlock_init (ACE_rwlock_t *rw, TCHAR name3[ACE_UNIQUE_NAME_LEN]; TCHAR name4[ACE_UNIQUE_NAME_LEN]; - ACE::unique_name ((const void *) &rw->lock_, - name1, - ACE_UNIQUE_NAME_LEN); - ACE::unique_name ((const void *) &rw->waiting_readers_, - name2, - ACE_UNIQUE_NAME_LEN); - ACE::unique_name ((const void *) &rw->waiting_writers_, - name3, - ACE_UNIQUE_NAME_LEN); - ACE::unique_name ((const void *) &rw->waiting_important_writer_, - name4, - ACE_UNIQUE_NAME_LEN); + ACE_OS::unique_name ((const void *) &rw->lock_, + name1, + ACE_UNIQUE_NAME_LEN); + ACE_OS::unique_name ((const void *) &rw->waiting_readers_, + name2, + ACE_UNIQUE_NAME_LEN); + ACE_OS::unique_name ((const void *) &rw->waiting_writers_, + name3, + ACE_UNIQUE_NAME_LEN); + ACE_OS::unique_name ((const void *) &rw->waiting_important_writer_, + name4, + ACE_UNIQUE_NAME_LEN); if (ACE_OS::mutex_init (&rw->lock_, type, name1, arg) == 0 && ACE_OS::cond_init (&rw->waiting_readers_, type, name2, arg) == 0 @@ -5789,6 +5924,272 @@ ACE_OS_CString::ACE_OS_CString (const char *s) return; } +ACE_Object_Manager_Base::Object_Manager_State + ACE_Object_Manager_Base::object_manager_state_ = + ACE_Object_Manager_Base::UNINITIALIZED_OBJ_MAN; + +# define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\ + {\ + TYPE *obj_p;\ + 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) + : 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 () +{ + return object_manager_state_ < RUNNING_OBJ_MAN; +} + +int +ACE_Object_Manager_Base::shutting_down () +{ + return object_manager_state_ > RUNNING_OBJ_MAN; +} + +extern "C" +void +ACE_OS_Object_Manager_Internal_Exit_Hook () +{ + 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 () +{ + if (instance_ == 0) + { + // Store the address of the instance so that instance () doesn't + // allocate a new one when called. + instance_ = this; + + init (); + } + // else if ACE_Object_Manager_instance_ was not 0, then then another + // ACE_Object_Manager has already been instantiated. Don't do + // anything, so that it will own all ACE_Object_Manager resources. +} + +ACE_OS_Object_Manager::~ACE_OS_Object_Manager () +{ + fini (); +} + +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); + ACE_ASSERT (instance_pointer == instance_); + +#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) + instance_pointer->dynamically_allocated_ = 1; +#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ + + } + + return instance_; +} + +int +ACE_OS_Object_Manager::init (void) +{ + if (object_manager_state_ < INITIALIZING_ACE_OS_OBJ_MAN) + { + // First, indicate that the ACE_OS_Object_Manager instance is being + // initialized. + object_manager_state_ = INITIALIZING_ACE_OS_OBJ_MAN; + +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK) + if (ACE_OS::thread_mutex_init (ACE_reinterpret_cast ( + ACE_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::init (1)"))); + ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_CLEANUP_LOCK) + if (ACE_OS::recursive_mutex_init (ACE_reinterpret_cast ( + ACE_recursive_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != + 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::init (2)"))); +# if defined (ACE_HAS_TSS_EMULATION) && \ + 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 (ACE_reinterpret_cast ( + ACE_recursive_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::init (3)"))); +# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# 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); + + // Finally, indicate that the ACE_OS_Object_Manager instance has + // been initialized. + object_manager_state_ = INITIALIZED_ACE_OS_OBJ_MAN; + + return 0; + } else { + // Had already initialized. + return -1; + } +} + +int +ACE_OS_Object_Manager::fini (void) +{ + if (instance_ == 0 || object_manager_state_ >= SHUTTING_DOWN_ACE_OS_OBJ_MAN) + // Too late. Or, maybe too early. Either fini () has already + // been called, or init () was never called. + return -1; + + // No mutex here. Only the main thread should destroy the singleton + // ACE_OS_Object_Manager instance. + + // First, indicate that the ACE_OS_Object_Manager instance is being + // shut down. + object_manager_state_ = SHUTTING_DOWN_ACE_OS_OBJ_MAN; + + // If another Object_Manager has registered for termination, do it. + if (next_) + next_->fini (); + + // 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 (ACE_OS::thread_mutex_destroy (ACE_reinterpret_cast ( + ACE_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::fini (1)"))); + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK) + if (ACE_OS::recursive_mutex_destroy (ACE_reinterpret_cast ( + ACE_recursive_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::fini (2)"))); + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_CLEANUP_LOCK) +# if defined (ACE_HAS_TSS_EMULATION) && \ + defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) + if (ACE_OS::recursive_mutex_destroy (ACE_reinterpret_cast ( + ACE_recursive_thread_mutex_t *, + ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT("%p\n"), + ASYS_TEXT("ACE_OS_Object_Manager::fini (3)"))); + ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t, + ACE_TSS_BASE_LOCK) +# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# endif /* ACE_MT_SAFE */ +#endif /* ! ACE_HAS_STATIC_PREALLOCATION */ + +#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) + if (dynamically_allocated_) + { + delete instance_; + instance_ = 0; + } +#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ + + // Indicate that the ACE_OS_Object_Manager instance has been shut down. + object_manager_state_ = SHUT_DOWN_ACE_OS_OBJ_MAN; + + return 0; +} + +#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) +class ACE_Export 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_Bridge *ACE_CE_Bridge::default_text_bridge_ = 0; @@ -5367,6 +5367,9 @@ public: size_t len); static char *strcpy (char *s, const char *t); + static char *strecpy (char *des, const char *src); + // Copies <src> to <des>, returning a pointer to the end of the + // copied region, rather than the beginning, as <strcpy> does. static char *strpbrk (char *s1, const char *s2); static const char *strpbrk (const char *s1, @@ -5442,6 +5445,7 @@ public: wint_t c); static const wchar_t *strchr (const wchar_t *s, wint_t c); + static wchar_t *strecpy (wchar_t *s, const wchar_t *t); static wchar_t *strrchr (wchar_t *s, wint_t c); static const wchar_t *strrchr (const wchar_t *s, @@ -5744,6 +5748,16 @@ public: static void thr_testcancel (void); static void thr_yield (void); + static void unique_name (const void *object, + LPTSTR name, + size_t length); + // This method uses process id and object pointer to come up with a + // machine wide unique name. The process ID will provide uniqueness + // between processes on the same machine. The "this" pointer of the + // <object> will provide uniqueness between other "live" objects in + // the same process. The uniqueness of this name is therefore only + // valid for the life of <object>. + static ACE_thread_t NULL_thread; // This is necessary to deal with POSIX pthreads and their use of // structures for thread ids. @@ -5802,8 +5816,8 @@ private: } // For use by ACE_Object_Manager only, to register its exit hook.. - friend class ACE_Object_Manager; - // Allow the ACE_Object_Manager to call set_exit_hook. + friend class ACE_OS_Object_Manager; + // Allow the ACE_OS_Object_Manager to call set_exit_hook. # if defined (ACE_WIN32) # if defined (ACE_HAS_WINCE) @@ -5818,6 +5832,150 @@ private: # endif /* ACE_WIN32 */ }; +class ACE_Export ACE_Object_Manager_Base +{ + // = TITLE + // Base class for ACE_Object_Manager(s). + // + // = DESCRIPTION + // Encapsulates the most useful ACE_Object_Manager data structures. +public: + static int starting_up (void); + // Returns 1 before 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 shutting_down (void); + // Returns 1 after 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.) + +# 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 */ + ACE_Object_Manager_Base (void); + // Default constructor. + + virtual ~ACE_Object_Manager_Base (void); + // Destructor. + +public: + virtual int init (void) = 0; + // Explicitly initialize. + + virtual int fini (void) = 0; + // Explicitly destroy. + + enum Object_Manager_State + { + UNINITIALIZED_OBJ_MAN = 0, + INITIALIZING_ACE_OS_OBJ_MAN, + INITIALIZED_ACE_OS_OBJ_MAN, + INITIALIZING_ACE_OBJ_MAN, + INITIALIZED_ACE_OBJ_MAN, + RUNNING_OBJ_MAN = INITIALIZED_ACE_OBJ_MAN, + SHUTTING_DOWN_ACE_OBJ_MAN, + SHUT_DOWN_ACE_OBJ_MAN, + SHUTTING_DOWN_ACE_OS_OBJ_MAN, + SHUT_DOWN_ACE_OS_OBJ_MAN, + TERMINATED_OBJ_MAN = SHUT_DOWN_ACE_OS_OBJ_MAN + }; + +protected: + static Object_Manager_State object_manager_state_; + // State of the program, from the ACE Object_Managers' points-of-view. + + u_int dynamically_allocated_; + // 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.) + + ACE_Object_Manager_Base *next_; + // Link to next Object_Manager, for chaining. +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 (); + + +class ACE_Export ACE_OS_Object_Manager : public ACE_Object_Manager_Base +{ +public: + virtual int init (void); + // Explicitly initialize. + + virtual int fini (void); + // Explicitly destroy. + + enum Preallocated_Object + { +# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_OS_MONITOR_LOCK, + ACE_TSS_CLEANUP_LOCK, +# if defined (ACE_HAS_TSS_EMULATION) && \ + defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) + ACE_TSS_BASE_LOCK, +# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ +# else + // 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_OS_EMPTY_PREALLOCATED_OBJECT, +# endif /* ACE_MT_SAFE */ + + ACE_OS_PREALLOCATED_OBJECTS // This enum value must be last! + }; + // Unique identifiers for preallocated objects. + +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 main () with + // ACE_HAS_NONSTATIC_OBJECT_MANAGER. + ACE_OS_Object_Manager (); + // Constructor. + + ~ACE_OS_Object_Manager (); + // Destructor. + +private: + 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 void ACE_OS_Object_Manager_Internal_Exit_Hook (); + // This class is for internal use by ACE_OS, etc., only. + + static ACE_OS_Object_Manager *instance (void); + // Accessor to singleton instance. + + static ACE_OS_Object_Manager *instance_; + // Singleton instance pointer. + + static void *preallocated_object[ACE_OS_PREALLOCATED_OBJECTS]; + // Table of preallocated objects. +}; + # if defined (ACE_HAS_WINCE) // **** Warning **** @@ -6381,6 +6539,19 @@ extern "C" ACE_Export void ace_mutex_lock_cleanup_adapter (void *args); // Also, create an ACE_Object_Manager static instance in "main ()". # include "ace/Object_Manager.h" +// ACE_MAIN_OBJECT_MANAGER defines the ACE_Object_Manager(s) that will +// be instantiated on the stack of main (). Note that it is only used +// when compiling main (): its value does not affect the contents of +// ace/OS.o. +# if defined (ACE_HAS_MINIMAL_ACE_OS) +# define ACE_MAIN_OBJECT_MANAGER \ + ACE_OS_Object_Manager ace_os_object_manager; +# else /* ! ACE_HAS_MINIMAL_ACE_OS */ +# define ACE_MAIN_OBJECT_MANAGER \ + ACE_OS_Object_Manager ace_os_object_manager; \ + ACE_Object_Manager ace_object_manager; +# endif /* ! ACE_HAS_MINIMAL_ACE_OS */ + # if defined (ACE_PSOSIM) // PSOSIM root lacks the standard argc, argv command line parameters, // create dummy argc and argv in the "real" main and pass to "user" main. @@ -6392,7 +6563,7 @@ ACE_MAIN () /* user's entry point, e.g., "main" w/out argc, argv */ \ { \ int argc = 1; /* dummy arg count */ \ char *argv[] = {"psosim"}; /* dummy arg list */ \ - ACE_Object_Manager ace_object_manager; /* has program lifetime */ \ + ACE_MAIN_OBJECT_MANAGER \ int ret_val = -1; /* assume the worst */ \ if (ACE_PSOS_Time_t::init_simulator_time ()) /* init simulator time */ \ { \ @@ -6417,7 +6588,7 @@ ACE_MAIN () /* user's entry point, e.g., "main" w/out argc, argv */ \ { \ int argc = 1; /* dummy arg count */ \ char *argv[] = {"root"}; /* dummy arg list */ \ - ACE_Object_Manager ace_object_manager; /* has program lifetime */ \ + ACE_MAIN_OBJECT_MANAGER \ ace_main_i (argc, argv); /* call user main, ignore result */ \ } \ int \ @@ -6428,7 +6599,7 @@ ace_main_i (int, char *[]); /* forward declaration */ \ int \ ACE_MAIN (int argc, char *argv[]) /* user's entry point, e.g., "main" */ \ { \ - ACE_Object_Manager ace_object_manager; /* has program lifetime */ \ + ACE_MAIN_OBJECT_MANAGER \ return ace_main_i (argc, argv); /* what the user calls "main" */ \ } \ int \ @@ -1385,6 +1385,19 @@ ACE_OS::strcpy (char *s, const char *t) return ::strcpy (s, t); } +ACE_INLINE char * +ACE_OS::strecpy (char *s, const char *t) +{ + // ACE_TRACE ("ACE_OS::strecpy"); + register char *dscan = s; + register const char *sscan = t; + + while ((*dscan++ = *sscan++) != '\0') + continue; + + return dscan; +} + ACE_INLINE int ACE_OS::to_lower (int c) { @@ -9371,6 +9384,19 @@ ACE_OS::atoi (const wchar_t *s) } ACE_INLINE wchar_t * +ACE_OS::strecpy (wchar_t *s, const wchar_t *t) +{ + // ACE_TRACE ("ACE_OS::strecpy"); + register wchar_t *dscan = s; + register const wchar_t *sscan = t; + + while ((*dscan++ = *sscan++) != '\0') + continue; + + return dscan; +} + +ACE_INLINE wchar_t * ACE_OS::strpbrk (wchar_t *s, const wchar_t *t) { // ACE_TRACE ("ACE_OS::wcspbrk"); diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp index 9eb2fb5370f..cff66a9f4f6 100644 --- a/ace/Object_Manager.cpp +++ b/ace/Object_Manager.cpp @@ -4,9 +4,9 @@ #include "ace/Object_Manager.h" #include "ace/Token_Manager.h" -#if !defined (ACE_HAS_WINCE) +#if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_OTHER) # include "ace/Naming_Context.h" -#endif /* !ACE_HAS_WINCE */ +#endif /* ! ACE_HAS_WINCE && ! ACE_LACKS_ACE_OTHER */ #include "ace/Service_Manager.h" #include "ace/Service_Config.h" #include "ace/Signal.h" @@ -39,14 +39,7 @@ ACE_RCSID(ace, Object_Manager, "$Id$") #endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS */ // Singleton pointer. -static ACE_Object_Manager *ACE_Object_Manager_instance_ = 0; - -int ACE_Object_Manager::starting_up_ = 1; - -int ACE_Object_Manager::shutting_down_ = 0; - -u_int ACE_Object_Manager::initialized_ = 0; -// Flag to allow handling of multiple calls to init (). +ACE_Object_Manager *ACE_Object_Manager::instance_ = 0; void *ACE_Object_Manager::preallocated_object[ ACE_Object_Manager::ACE_PREALLOCATED_OBJECTS] = { 0 }; @@ -100,9 +93,9 @@ public: ~ACE_Object_Manager_Preallocations (void); private: -#if !defined (ACE_HAS_WINCE) +#if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_OTHER) ACE_Static_Svc_Descriptor ace_svc_desc_ACE_Naming_Context; -#endif /* !ACE_HAS_WINCE */ +#endif /* ! ACE_HAS_WINCE && ! ACE_LACKS_ACE_OTHER */ ACE_Static_Svc_Descriptor ace_svc_desc_ACE_Service_Manager; }; @@ -113,19 +106,11 @@ extern "C" ACE_Export ACE_Service_Object * _make_ACE_Service_Manager (ACE_Service_Object_Exterminator *); -extern "C" -void -ACE_Object_Manager_Internal_Exit_Hook () -{ - if (ACE_Object_Manager_instance_) - ACE_Object_Manager_instance_->fini (); -} - ACE_Object_Manager_Preallocations::ACE_Object_Manager_Preallocations (void) { // Define the static services. This macro call creates static // service descriptors that are used for initialization below. -#if !defined (ACE_HAS_WINCE) +#if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_OTHER) ACE_STATIC_SVC_DEFINE (ACE_Naming_Context_initializer, ASYS_TEXT ("ACE_Naming_Context"), ACE_SVC_OBJ_T, @@ -133,7 +118,7 @@ ACE_Object_Manager_Preallocations::ACE_Object_Manager_Preallocations (void) ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, 0) -#endif /* !ACE_HAS_WINCE */ +#endif /* ! ACE_HAS_WINCE && ! ACE_LACKS_ACE_OTHER */ ACE_STATIC_SVC_DEFINE (ACE_Service_Manager_initializer, ASYS_TEXT ("ACE_Service_Manager"), @@ -145,19 +130,19 @@ ACE_Object_Manager_Preallocations::ACE_Object_Manager_Preallocations (void) // Initialize the static service objects using the descriptors created // above. -#if !defined (ACE_HAS_WINCE) +#if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_OTHER) ace_svc_desc_ACE_Naming_Context = ace_svc_desc_ACE_Naming_Context_initializer; -#endif /* !ACE_HAS_WINCE */ +#endif /* ! ACE_HAS_WINCE && ! ACE_LACKS_ACE_OTHER */ ace_svc_desc_ACE_Service_Manager = ace_svc_desc_ACE_Service_Manager_initializer; // Add to the list of static configured services. -#if !defined (ACE_HAS_WINCE) +#if !defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_ACE_OTHER) ACE_Service_Config::static_svcs ()-> insert (&ace_svc_desc_ACE_Naming_Context); -#endif /* !ACE_HAS_WINCE */ +#endif /* ! ACE_HAS_WINCE && ! ACE_LACKS_ACE_OTHER */ ACE_Service_Config::static_svcs ()-> insert (&ace_svc_desc_ACE_Service_Manager); @@ -167,32 +152,18 @@ ACE_Object_Manager_Preallocations::~ACE_Object_Manager_Preallocations (void) { } -ACE_Object_Manager_Base::ACE_Object_Manager_Base (void) - : registered_objects_ (0) -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - , internal_lock_ (new ACE_Recursive_Thread_Mutex) - , singleton_null_lock_ (0) - , singleton_thread_locks_ (0) - , singleton_mutex_locks_ (0) - , singleton_recursive_lock_ (0) - , singleton_rw_locks_ (0) -# endif /* ACE_MT_SAFE */ -{ -} - int ACE_Object_Manager::init (void) { - if (initialized_ == 0) + if (object_manager_state_ < INITIALIZING_ACE_OBJ_MAN) { - initialized_ = 1; + // First, indicate that the ACE_Object_Manager instance is being + // initialized. + object_manager_state_ = INITIALIZING_ACE_OBJ_MAN; - if (ACE_Object_Manager_instance_ == 0) - { - // Allocate the ACE_Object_Manager instance on the heap. Assume - // that the application will call fini () to destroy it. - ACE_Object_Manager::instance (); - } + // Make sure that the ACE_OS_Object_Manager has been created, + // and register with it for chained fini (). + ACE_OS_Object_Manager::instance ()->next_ = this; // Allocate the preallocated (hard-coded) object instances. ACE_PREALLOCATE_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK) @@ -204,7 +175,6 @@ ACE_Object_Manager::init (void) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_LOG_MSG_INSTANCE_LOCK) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_MT_CORBA_HANDLER_LOCK) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK) - ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_OS_MONITOR_LOCK) ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex, ACE_SIG_HANDLER_LOCK) ACE_PREALLOCATE_OBJECT (ACE_Null_Mutex, ACE_SINGLETON_NULL_LOCK) @@ -215,19 +185,12 @@ ACE_Object_Manager::init (void) ACE_TOKEN_MANAGER_CREATION_LOCK) ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX, ACE_TOKEN_INVARIANTS_CREATION_LOCK) - ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex, - ACE_TSS_CLEANUP_LOCK) -# if defined (ACE_HAS_TSS_EMULATION) && \ - defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) - ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex, - ACE_TSS_BASE_LOCK) -# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ # endif /* ACE_MT_SAFE */ // Do this after the allocation of ACE_STATIC_OBJECT_LOCK. It // shouldn't matter, but just in case // ACE_Static_Object_Lock::instance () gets changed . . . - ACE_NEW_RETURN (ACE_Object_Manager_instance_->registered_objects_, + ACE_NEW_RETURN (registered_objects_, ACE_Unbounded_Queue<ACE_Cleanup_Info>, -1); // Hooks for preallocated objects and arrays provided by application. @@ -236,28 +199,19 @@ ACE_Object_Manager::init (void) # if defined (ACE_HAS_TSS_EMULATION) // Initialize the main thread's TS storage. - ACE_TSS_Emulation::tss_open ( - ACE_Object_Manager_instance_->ts_storage_); + ACE_TSS_Emulation::tss_open (ts_storage_); # endif /* ACE_HAS_TSS_EMULATION */ - // Open Winsock (no-op on other platforms). - ACE_OS::socket_init (ACE_WSOCK_VERSION); - - ACE_NEW_RETURN (ACE_Object_Manager_instance_->preallocations_, - ACE_Object_Manager_Preallocations, -1); + ACE_NEW_RETURN (preallocations_, ACE_Object_Manager_Preallocations, -1); // Open the main thread's ACE_Log_Msg. (void) ACE_LOG_MSG; - ACE_NEW_RETURN (ACE_Object_Manager_instance_->default_mask_, - ACE_Sig_Set (1), -1); - - // Register the exit hook, for use by ACE_OS::exit (). - ACE_OS::set_exit_hook (ACE_Object_Manager_Internal_Exit_Hook); + ACE_NEW_RETURN (default_mask_, ACE_Sig_Set (1), -1); // Finally, indicate that the ACE_Object_Manager instance has - // been constructed. - ACE_Object_Manager_instance_->starting_up_ = 0; + // been initialized. + object_manager_state_ = INITIALIZED_ACE_OBJ_MAN; return 0; } else { @@ -269,8 +223,7 @@ ACE_Object_Manager::init (void) int ACE_Object_Manager::fini (void) { - if (ACE_Object_Manager_instance_ == 0 || \ - ACE_Object_Manager_instance_->shutting_down_ == 1) + if (instance_ == 0 || object_manager_state_ >= SHUTTING_DOWN_ACE_OBJ_MAN) // Too late. Or, maybe too early. Either fini () has already // been called, or init () was never called. return -1; @@ -278,10 +231,9 @@ ACE_Object_Manager::fini (void) // No mutex here. Only the main thread should destroy the singleton // ACE_Object_Manager instance. - // First, indicate that the ACE_Object_Manager instance is (being) - // destroyed. If an object tries to register after this, it will be - // refused. - ACE_Object_Manager_instance_->shutting_down_ = 1; + // First, indicate that the ACE_Object_Manager instance is being + // shut down. + object_manager_state_ = SHUTTING_DOWN_ACE_OBJ_MAN; ACE_Trace::stop_tracing (); @@ -293,9 +245,8 @@ ACE_Object_Manager::fini (void) // Call all registered cleanup hooks, in reverse order of // registration. - while (ACE_Object_Manager_instance_->registered_objects_ && - ACE_Object_Manager_instance_->registered_objects_-> - dequeue_head (info) != -1) + while (registered_objects_ && + registered_objects_->dequeue_head (info) != -1) { if (info.cleanup_hook_ == (ACE_CLEANUP_FUNC) ace_cleanup_destroyer) // The object is an ACE_Cleanup. @@ -315,11 +266,8 @@ ACE_Object_Manager::fini (void) // all ACE library services and singletons. ACE_Service_Config::close (); - // Close down Winsock (no-op on other platforms). - ACE_OS::socket_fini (); - - delete ACE_Object_Manager_instance_->preallocations_; - ACE_Object_Manager_instance_->preallocations_ = 0; + delete preallocations_; + preallocations_ = 0; // Close the ACE_Allocator. ACE_Allocator::close_singleton (); @@ -328,16 +276,16 @@ ACE_Object_Manager::fini (void) // Hooks for deletion of preallocated objects and arrays provided by // application. ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS - ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS + ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS - // Cleanup the dynamically preallocated arrays. - // (none) + // Cleanup the dynamically preallocated arrays. + // (none) - // Cleanup the dynamically preallocated objects. - ACE_DELETE_PREALLOCATED_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK) + // Cleanup the dynamically preallocated objects. + ACE_DELETE_PREALLOCATED_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK) #if defined (ACE_HAS_THREADS) - ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex, - ACE_STATIC_OBJECT_LOCK) + ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex, + ACE_STATIC_OBJECT_LOCK) #endif /* ACE_HAS_THREADS */ # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, @@ -345,7 +293,6 @@ ACE_Object_Manager::fini (void) ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_MT_CORBA_HANDLER_LOCK) ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK) - ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_OS_MONITOR_LOCK) ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex, ACE_SIG_HANDLER_LOCK) ACE_DELETE_PREALLOCATED_OBJECT (ACE_Null_Mutex, ACE_SINGLETON_NULL_LOCK) @@ -356,13 +303,6 @@ ACE_Object_Manager::fini (void) ACE_TOKEN_MANAGER_CREATION_LOCK) ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX, ACE_TOKEN_INVARIANTS_CREATION_LOCK) - ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex, - ACE_TSS_CLEANUP_LOCK) -# if defined (ACE_HAS_TSS_EMULATION) && \ - defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) - ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex, - ACE_TSS_BASE_LOCK) -# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ # endif /* ACE_MT_SAFE */ #endif /* ! ACE_HAS_STATIC_PREALLOCATION */ @@ -370,33 +310,48 @@ ACE_Object_Manager::fini (void) ACE_Static_Object_Lock::cleanup_lock (); #endif /* ACE_HAS_THREADS */ - delete ACE_Object_Manager_instance_->default_mask_; - ACE_Object_Manager_instance_->default_mask_ = 0; + delete default_mask_; + default_mask_ = 0; #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) - if (ACE_Object_Manager_instance_->dynamically_allocated_) + if (dynamically_allocated_) { - delete ACE_Object_Manager_instance_; - ACE_Object_Manager_instance_ = 0; + delete instance_; + instance_ = 0; } #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ + // Indicate that the ACE_Object_Manager instance has been shut down. + object_manager_state_ = SHUT_DOWN_ACE_OBJ_MAN; + + // Then, ensure that the ACE_OS_Object_Manager gets shut down. + if (ACE_OS_Object_Manager::instance_) + ACE_OS_Object_Manager::instance ()->fini (); + return 0; } ACE_Object_Manager::ACE_Object_Manager (void) // With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call to // ACE_OS::tss_open () in the function body. - : dynamically_allocated_ (0) + : registered_objects_ (0) , preallocations_ (0) , default_mask_ (0) , ace_service_config_sig_handler_ (0) +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + , internal_lock_ (new ACE_Recursive_Thread_Mutex) + , singleton_null_lock_ (0) + , singleton_thread_locks_ (0) + , singleton_mutex_locks_ (0) + , singleton_recursive_lock_ (0) + , singleton_rw_locks_ (0) +# endif /* ACE_MT_SAFE */ { - if (ACE_Object_Manager_instance_ == 0) + if (instance_ == 0) { // Store the address of the instance so that instance () doesn't // allocate a new one when called. - ACE_Object_Manager_instance_ = this; + instance_ = this; // Construct the ACE_Service_Config's signal handler. ACE_NEW (ace_service_config_sig_handler_, @@ -405,10 +360,9 @@ ACE_Object_Manager::ACE_Object_Manager (void) init (); } - // else if ACE_Object_Manager_instance_ was not 0, then then another - // ACE_Object_Manager has already been instantiated. - // Don't do anything, so that it will own all - // ACE_Object_Manager resources. + // else if instance_ was not 0, then then another + // ACE_Object_Manager has already been instantiated. Don't do + // anything, so that it will own all ACE_Object_Manager resources. } ACE_Object_Manager * @@ -418,12 +372,12 @@ ACE_Object_Manager::instance (void) // instances, or before any other threads have been created in // the process. So, it's not thread safe. - if (ACE_Object_Manager_instance_ == 0) + if (instance_ == 0) { ACE_Object_Manager *instance_pointer; ACE_NEW_RETURN (instance_pointer, ACE_Object_Manager, 0); - ACE_ASSERT (instance_pointer == ACE_Object_Manager_instance_); + ACE_ASSERT (instance_pointer == instance_); #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) instance_pointer->dynamically_allocated_ = 1; @@ -433,22 +387,10 @@ ACE_Object_Manager::instance (void) } else { - return ACE_Object_Manager_instance_; + return instance_; } } -int -ACE_Object_Manager::starting_up () -{ - return starting_up_; -} - -int -ACE_Object_Manager::shutting_down () -{ - return shutting_down_; -} - ACE_Sig_Set & ACE_Object_Manager::default_mask (void) { @@ -461,7 +403,7 @@ ACE_Object_Manager::at_exit_i (void *object, void *param) { ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, - *ACE_Object_Manager_instance_->internal_lock_, -1)); + *instance_->internal_lock_, -1)); if (shutting_down ()) { @@ -497,10 +439,9 @@ ACE_Object_Manager::at_exit_i (void *object, #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) int -ACE_Object_Manager_Base::get_singleton_lock (ACE_Null_Mutex *&lock) +ACE_Object_Manager::get_singleton_lock (ACE_Null_Mutex *&lock) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (starting_up () || shutting_down ()) { // The preallocated lock has not been constructed yet. // Therefore, the program is single-threaded at this point. Or, @@ -533,12 +474,11 @@ ACE_Object_Manager_Base::get_singleton_lock (ACE_Null_Mutex *&lock) } int -ACE_Object_Manager_Base::get_singleton_lock (ACE_Thread_Mutex *&lock) +ACE_Object_Manager::get_singleton_lock (ACE_Thread_Mutex *&lock) { if (lock == 0) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (starting_up () || shutting_down ()) { // The Object_Manager and its internal lock have not been // constructed yet. Therefore, the program is single- @@ -622,12 +562,11 @@ ACE_Object_Manager_Base::get_singleton_lock (ACE_Thread_Mutex *&lock) } int -ACE_Object_Manager_Base::get_singleton_lock (ACE_Mutex *&lock) +ACE_Object_Manager::get_singleton_lock (ACE_Mutex *&lock) { if (lock == 0) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (starting_up () || shutting_down ()) { // The Object_Manager and its internal lock have not been // constructed yet. Therefore, the program is single- @@ -711,10 +650,9 @@ ACE_Object_Manager_Base::get_singleton_lock (ACE_Mutex *&lock) } int -ACE_Object_Manager_Base::get_singleton_lock (ACE_Recursive_Thread_Mutex *&lock) +ACE_Object_Manager::get_singleton_lock (ACE_Recursive_Thread_Mutex *&lock) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (starting_up () || shutting_down ()) { // The preallocated lock has not been constructed yet. // Therefore, the program is single-threaded at this point. Or, @@ -746,12 +684,11 @@ ACE_Object_Manager_Base::get_singleton_lock (ACE_Recursive_Thread_Mutex *&lock) } int -ACE_Object_Manager_Base::get_singleton_lock (ACE_RW_Thread_Mutex *&lock) +ACE_Object_Manager::get_singleton_lock (ACE_RW_Thread_Mutex *&lock) { if (lock == 0) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (starting_up () || shutting_down ()) { // The Object_Manager and its internal lock have not been // constructed yet. Therefore, the program is single- @@ -839,43 +776,35 @@ ACE_Object_Manager_Base::get_singleton_lock (ACE_RW_Thread_Mutex *&lock) // NOTE: this function needs to appear _after_ the // get_singleton_lock () functions in order to compile with // g++ 2.7.2.3. -ACE_Object_Manager_Base::~ACE_Object_Manager_Base (void) +ACE_Object_Manager::~ACE_Object_Manager (void) { -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - delete internal_lock_; - internal_lock_ = 0; - - delete singleton_null_lock_; - singleton_null_lock_ = 0; + if (fini () != -1) + { + delete ace_service_config_sig_handler_; + ace_service_config_sig_handler_ = 0; - delete singleton_thread_locks_; - singleton_thread_locks_ = 0; + delete registered_objects_; + registered_objects_ = 0; - delete singleton_mutex_locks_; - singleton_mutex_locks_ = 0; +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + delete internal_lock_; + internal_lock_ = 0; - delete singleton_recursive_lock_; - singleton_recursive_lock_ = 0; + delete singleton_null_lock_; + singleton_null_lock_ = 0; - delete singleton_rw_locks_; - singleton_rw_locks_ = 0; -#endif /* ACE_MT_SAFE */ + delete singleton_thread_locks_; + singleton_thread_locks_ = 0; - delete registered_objects_; - registered_objects_ = 0; -} + delete singleton_mutex_locks_; + singleton_mutex_locks_ = 0; -ACE_Object_Manager::~ACE_Object_Manager (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 */ + delete singleton_recursive_lock_; + singleton_recursive_lock_ = 0; - if (fini () != -1) - { - delete ace_service_config_sig_handler_; - ace_service_config_sig_handler_ = 0; + delete singleton_rw_locks_; + singleton_rw_locks_ = 0; +#endif /* ACE_MT_SAFE */ } // else fini () had already been called. It would be safe // to delete the 0 pointers again, but this allows us to @@ -883,11 +812,10 @@ ACE_Object_Manager::~ACE_Object_Manager (void) } #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) -class ACE_Export ACE_Object_Manager_Destroyer +class ACE_Export ACE_Object_Manager_Manager // = TITLE - // Ensure that the <ACE_Object_Manager> gets initialized before any - // application threads have been spawned, and destroyed at program - // termination. + // Ensure that the <ACE_Object_Manager> gets initialized at + // program startup, and destroyed at program termination. // // = DESCRIPTION // Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this @@ -895,15 +823,15 @@ class ACE_Export ACE_Object_Manager_Destroyer // is called. And it gets destroyed after main () returns. { public: - ACE_Object_Manager_Destroyer (void); - ~ACE_Object_Manager_Destroyer (void); + ACE_Object_Manager_Manager (void); + ~ACE_Object_Manager_Manager (void); private: ACE_thread_t saved_main_thread_id_; // Save the main thread ID, so that destruction can be suppressed. }; -ACE_Object_Manager_Destroyer::ACE_Object_Manager_Destroyer (void) +ACE_Object_Manager_Manager::ACE_Object_Manager_Manager (void) : saved_main_thread_id_ (ACE_OS::thr_self ()) { // Ensure that the Object_Manager gets initialized before any @@ -913,20 +841,20 @@ ACE_Object_Manager_Destroyer::ACE_Object_Manager_Destroyer (void) (void) ACE_Object_Manager::instance (); } -ACE_Object_Manager_Destroyer::~ACE_Object_Manager_Destroyer (void) +ACE_Object_Manager_Manager::~ACE_Object_Manager_Manager (void) { if (ACE_OS::thr_equal (ACE_OS::thr_self (), saved_main_thread_id_)) { - delete ACE_Object_Manager_instance_; - ACE_Object_Manager_instance_ = 0; + delete ACE_Object_Manager::instance_; + ACE_Object_Manager::instance_ = 0; } // else if this destructor is not called by the main thread, then do // not delete the ACE_Object_Manager. That causes problems, on // WIN32 at least. } -static ACE_Object_Manager_Destroyer ACE_Object_Manager_Destroyer_internal; +static ACE_Object_Manager_Manager ACE_Object_Manager_Manager_instance; #endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */ #if defined (ACE_HAS_THREADS) @@ -939,8 +867,8 @@ ACE_Static_Object_Lock_lock = 0; ACE_Recursive_Thread_Mutex * ACE_Static_Object_Lock::instance (void) { - if (ACE_Object_Manager::starting_up () || - ACE_Object_Manager::shutting_down ()) + if (ACE_Object_Manager_Base::starting_up () || \ + ACE_Object_Manager_Base::shutting_down ()) { // The preallocated ACE_STATIC_OBJECT_LOCK has not been // constructed yet. Therefore, the program is single-threaded diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h index 15befcf5c4c..43640239d3d 100644 --- a/ace/Object_Manager.h +++ b/ace/Object_Manager.h @@ -54,89 +54,6 @@ template <class T> class ACE_Array; #endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */ -class ACE_Export ACE_Object_Manager_Base -{ - // = TITLE - // Base class for ACE_Object_Manager(s). - // - // = DESCRIPTION - // Encapsulates the most useful ACE_Object_Manager data structures. -# 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 */ - ACE_Object_Manager_Base (void); - // Default constructor. - - virtual ~ACE_Object_Manager_Base (void); - // Destructor. - - ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_; - // Keeps track of all registered objects. - -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Recursive_Thread_Mutex *internal_lock_; - // Lock that is used to guard internal structures. - - ACE_Cleanup_Adapter<ACE_Null_Mutex> *singleton_null_lock_; - // Null lock for guarding singleton creation. - - ACE_Array<ACE_Thread_Mutex *> *singleton_thread_locks_; - // Array of locks for guarding singleton creation. - - ACE_Array<ACE_Mutex *> *singleton_mutex_locks_; - // Array of locks for guarding singleton creation. - - ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> *singleton_recursive_lock_; - // Lock for guarding singleton creation. - - ACE_Array<ACE_RW_Thread_Mutex *> *singleton_rw_locks_; - // Array of locks for guarding singleton creation. - -public: - // = The <get_singleton_lock> accessors are for internal - // use by ACE_Singleton _only_. - - static int get_singleton_lock (ACE_Null_Mutex *&); - // 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. The argument is ignored -- it is - // only used for overload resolution. - - static int get_singleton_lock (ACE_Thread_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. The argument is - // ignored -- it is only used for overload resolution. - - static int get_singleton_lock (ACE_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. The argument is ignored -- it is - // only used for overload resolution. - - static int get_singleton_lock (ACE_Recursive_Thread_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_RW_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. -#endif /* ACE_MT_SAFE */ - -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 &); -}; - class ACE_Export ACE_Object_Manager : public ACE_Object_Manager_Base { // = TITLE @@ -214,6 +131,9 @@ class ACE_Export ACE_Object_Manager : public ACE_Object_Manager_Base // building the ACE library and your applications. This #define // is enabled in some config files that are supplied with ACE. // + // 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 @@ -253,14 +173,20 @@ class ACE_Export ACE_Object_Manager : public ACE_Object_Manager_Base // Greif <jmg@trivida.com> 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 creating + // it on the stack of main (), another alternative is to #define + // ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER. With that + // #define, the application _must_ call ACE::init () at the + // start of the program, and call ACE::fini () at the end. public: - static int init (void); - // Explicity initialize (construct the singleton instance of) the + virtual int init (void); + // Explicitly initialize (construct the singleton instance of) the // ACE_Object_Manager. - static int fini (void); - // Explicity destroy the singleton instance of the + virtual int fini (void); + // Explicitly destroy the singleton instance of the // ACE_Object_Manager. static int at_exit (ACE_Cleanup *object, void *param = 0); @@ -309,17 +235,12 @@ public: 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, -# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) - ACE_TSS_BASE_LOCK, -# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */ #endif /* ACE_MT_SAFE */ // Hook for preallocated objects provided by application. @@ -348,40 +269,12 @@ public: // ace/Managed_Object.h for information on accessing preallocated // arrays. - static int starting_up (void); - // Returns 1 before 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 shutting_down (void); - // Returns 1 after 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 ACE_Sig_Set &default_mask (void); // Accesses a default signal set used in ACE_Sig_Guard methods. private: - static int starting_up_; - // Flag indicating whether the program is starting up. - - static int shutting_down_; - // Flag indicating whether the program is shutting down. - - static u_int initialized_; - // Flag to allow graceful handling of multiple calls to init (). - - u_int dynamically_allocated_; - // 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.) + ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_; + // Keeps track of all registered objects. ACE_Object_Manager_Preallocations *preallocations_; // Preallocated objects collection. @@ -396,6 +289,40 @@ private: // Register an object or array for deletion at program termination. // See description of static version above for return values. +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +public: + // = The <get_singleton_lock> accessors are for internal + // use by ACE_Singleton _only_. + + static int get_singleton_lock (ACE_Null_Mutex *&); + // 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. The argument is ignored -- it is + // only used for overload resolution. + + static int get_singleton_lock (ACE_Thread_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. The argument is + // ignored -- it is only used for overload resolution. + + static int get_singleton_lock (ACE_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. The argument is ignored -- it is + // only used for overload resolution. + + static int get_singleton_lock (ACE_Recursive_Thread_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_RW_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. +#endif /* ACE_MT_SAFE */ + public: // For internal use only by ACE_Managed_Objects. @@ -419,13 +346,36 @@ public: ~ACE_Object_Manager (void); private: + static ACE_Object_Manager *instance_; + // Singleton pointer. + +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + ACE_Recursive_Thread_Mutex *internal_lock_; + // Lock that is used to guard internal structures. + + ACE_Cleanup_Adapter<ACE_Null_Mutex> *singleton_null_lock_; + // Null lock for guarding singleton creation. + + ACE_Array<ACE_Thread_Mutex *> *singleton_thread_locks_; + // Array of locks for guarding singleton creation. + + ACE_Array<ACE_Mutex *> *singleton_mutex_locks_; + // Array of locks for guarding singleton creation. + + ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> *singleton_recursive_lock_; + // Lock for guarding singleton creation. + + ACE_Array<ACE_RW_Thread_Mutex *> *singleton_rw_locks_; + // Array of locks for guarding singleton creation. +#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]; #endif /* ACE_HAS_TSS_EMULATION */ #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) - friend class ACE_Object_Manager_Destroyer; + friend class ACE_Object_Manager_Manager; #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ // Disallow copying by not implementing the following . . . |