summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-03-01 19:15:33 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-03-01 19:15:33 +0000
commit1f75eb70a72bae885c665f3b91b73b13b836b491 (patch)
treec08cf828dea0abb4d47ebe6f9df3c58468866ce7
parent0e81d140a777185bbc875526fc19d68a1dcea83f (diff)
downloadATCD-1f75eb70a72bae885c665f3b91b73b13b836b491.tar.gz
added ACE_OS_Object_Manager
-rw-r--r--ace/OS.cpp613
-rw-r--r--ace/OS.h181
-rw-r--r--ace/OS.i26
-rw-r--r--ace/Object_Manager.cpp296
-rw-r--r--ace/Object_Manager.h196
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;
diff --git a/ace/OS.h b/ace/OS.h
index d17e0f287e8..4f8dec41cb5 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -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 \
diff --git a/ace/OS.i b/ace/OS.i
index d2a6339838a..c77f508ffb8 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -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 . . .