summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-22 21:34:03 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-22 21:34:03 +0000
commit033b2beefbd5d485b370c4a18372643e42ee094c (patch)
tree3be789bff0ab97153eea9548103f125117688578
parentd065f02a939b86e07a34f24e2fd001f7f72deaaf (diff)
downloadATCD-033b2beefbd5d485b370c4a18372643e42ee094c.tar.gz
moved ace_singleton_lock_ to Object_Manager
-rw-r--r--ace/Object_Manager.cpp142
-rw-r--r--ace/Object_Manager.h54
-rw-r--r--ace/Singleton.cpp128
-rw-r--r--ace/Singleton.h14
4 files changed, 233 insertions, 105 deletions
diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp
index 520482daa1c..32a396de702 100644
--- a/ace/Object_Manager.cpp
+++ b/ace/Object_Manager.cpp
@@ -33,6 +33,9 @@
// Static data.
ACE_Object_Manager *ACE_Object_Manager::instance_ = 0;
+int ACE_Object_Manager::starting_up_ = 1;
+int ACE_Object_Manager::shutting_down_ = 0;
+
void *ACE_Object_Manager::managed_object[ACE_MAX_MANAGED_OBJECTS] = { 0 };
u_int ACE_Object_Manager::next_managed_object = 0;
@@ -79,8 +82,8 @@ void *ACE_Object_Manager::preallocated_array[
preallocated_array[ID] = 0;
#endif /* ACE_HAS_STATIC_PREALLOCATION */
+
ACE_Object_Manager::ACE_Object_Manager (void)
- : shutting_down_(0)
// , lock_ is initialized in the function body.
// With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call
// to ACE_OS::tss_open () in the function body.
@@ -106,6 +109,10 @@ ACE_Object_Manager::ACE_Object_Manager (void)
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)
+ ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
+ ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
+ ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_SINGLETON_THREAD_LOCK)
ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_SVC_HANDLER_LOCK)
ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX,
@@ -129,6 +136,10 @@ ACE_Object_Manager::ACE_Object_Manager (void)
// Open the main thread's ACE_Log_Msg.
(void) ACE_LOG_MSG;
+
+ // Finally, indicate that the ACE_Object_Manager instance has been
+ // constructed.
+ ACE_Object_Manager::starting_up_ = 0;
}
ACE_Object_Manager::~ACE_Object_Manager (void)
@@ -136,26 +147,32 @@ ACE_Object_Manager::~ACE_Object_Manager (void)
// No mutex here. Only the main thread should destroy the
// singleton ACE_Object_Manager instance.
- ACE_Cleanup_Info info;
+ // 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::shutting_down_ = 1;
- // Call all registered cleanup hooks, in reverse order of
- // registration. Before starting, mark this object as being
- // destroyed - then if during the course of shutting things down,
- // some object tries to register, it won't be.
- shutting_down_ = 1;
ACE_Trace::stop_tracing ();
+ ACE_Cleanup_Info info;
+
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
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.
- ace_cleanup_destroyer ((ACE_Cleanup *) info.object_, info.param_);
- else
- (*info.cleanup_hook_) (info.object_, info.param_);
-
- // This call closes and deletes all ACE library services and
- // singletons. This closes the ACE_Thread_Manager, which cleans up
- // all running threads.
+ {
+ if (info.cleanup_hook_ == (ACE_CLEANUP_FUNC) ace_cleanup_destroyer)
+ {
+ // The object is an ACE_Cleanup.
+ ace_cleanup_destroyer ((ACE_Cleanup *) info.object_, info.param_);
+ }
+ else
+ {
+ (*info.cleanup_hook_) (info.object_, info.param_);
+ }
+ }
+
+ // Close and delete all ACE library services and singletons.
ACE_Service_Config::close ();
// Close the main thread's TSS, including its Log_Msg instance.
@@ -199,6 +216,10 @@ ACE_Object_Manager::~ACE_Object_Manager (void)
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)
+ ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
+ ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
+ ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_SINGLETON_THREAD_LOCK)
ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_SVC_HANDLER_LOCK)
ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX,
@@ -224,13 +245,25 @@ ACE_Object_Manager::instance (void)
}
int
+ACE_Object_Manager::starting_up ()
+{
+ return ACE_Object_Manager::starting_up_;
+}
+
+int
+ACE_Object_Manager::shutting_down ()
+{
+ return ACE_Object_Manager::shutting_down_;
+}
+
+int
ACE_Object_Manager::at_exit_i (void *object,
ACE_CLEANUP_FUNC cleanup_hook,
void *param)
{
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock_, -1));
- if (shutting_down_)
+ if (shutting_down ())
{
errno = EAGAIN;
return -1;
@@ -260,6 +293,34 @@ ACE_Object_Manager::at_exit_i (void *object,
return registered_objects_->enqueue_head (new_info);
}
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+
+ACE_Null_Mutex *
+ACE_Object_Manager::get_singleton_lock (ACE_Null_Mutex *)
+{
+ // Use the Object_Manager's preallocated lock.
+ return ACE_Managed_Object<ACE_Null_Mutex>::get_preallocated_object
+ (ACE_Object_Manager::ACE_SINGLETON_NULL_LOCK);
+}
+
+ACE_Thread_Mutex *
+ACE_Object_Manager::get_singleton_lock (ACE_Thread_Mutex *)
+{
+ // Use the Object_Manager's preallocated lock.
+ return ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
+ (ACE_Object_Manager::ACE_SINGLETON_THREAD_LOCK);
+}
+
+ACE_Recursive_Thread_Mutex *
+ACE_Object_Manager::get_singleton_lock (ACE_Recursive_Thread_Mutex*)
+{
+ // Use the Object_Manager's preallocated lock.
+ return ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::
+ get_preallocated_object (ACE_Object_Manager::
+ ACE_SINGLETON_RECURSIVE_THREAD_LOCK);
+}
+#endif /* ACE_MT_SAFE */
+
#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
class ACE_Export ACE_Object_Manager_Destroyer
// = TITLE
@@ -297,25 +358,44 @@ static ACE_Object_Manager_Destroyer ACE_Object_Manager_Destroyer_internal;
#endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */
#if defined (ACE_HAS_THREADS)
- ACE_Recursive_Thread_Mutex *
- ACE_Static_Object_Lock::instance (void)
- {
-#if 1
- // Temporary hack until we get rid of all statics from ACE library.
- // The ACE static services need this . . .
- static ACE_Recursive_Thread_Mutex _mutex;
- return &_mutex;
-#else /* ! 1 */
- return ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::
- get_preallocated_object(ACE_Object_Manager::ACE_STATIC_OBJECT_LOCK);
-#endif /* ! 1 */
- }
+ACE_Recursive_Thread_Mutex *
+ACE_Static_Object_Lock::instance (void)
+{
+ if (ACE_Object_Manager::starting_up ())
+ {
+ // The preallocated ACE_STATIC_OBJECT_LOCK has not been
+ // constructed yet. The program is single-threaded at this
+ // point. Allocate a lock to use, for interface compatibility,
+ // though there should be no contention on it.
+ static ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> *lock = 0;
+
+ if (lock == 0)
+ {
+ ACE_NEW_RETURN (lock,
+ ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>,
+ 0);
+
+ // Register for destruction with ACE_Object_Manager.
+ ACE_Object_Manager::at_exit (lock);
+ }
+
+ return &lock->object ();
+ }
+ else
+ {
+ // Return the preallocated ACE_STATIC_OBJECT_LOCK.
+ return ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::
+ get_preallocated_object(ACE_Object_Manager::ACE_STATIC_OBJECT_LOCK);
+ }
+}
#endif /* ACE_HAS_THREADS */
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ template class ACE_Cleanup_Adapter<ACE_Null_Mutex>;
template class ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>;
template class ACE_Cleanup_Adapter<ACE_Thread_Mutex>;
+ template class ACE_Managed_Object<ACE_Null_Mutex>;
template class ACE_Managed_Object<ACE_Recursive_Thread_Mutex>;
template class ACE_Managed_Object<ACE_Thread_Mutex>;
# endif /* ACE_MT_SAFE */
@@ -326,8 +406,10 @@ template class ACE_Unbounded_Queue_Iterator<ACE_Cleanup_Info>;
template class ACE_Node<ACE_Cleanup_Info>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# pragma instantiate ACE_Cleanup_Adapter<ACE_Null_Mutex>
# pragma instantiate ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>
# pragma instantiate ACE_Cleanup_Adapter<ACE_Thread_Mutex>
+# pragma instantiate ACE_Managed_Object<ACE_Null_Mutex>
# pragma instantiate ACE_Managed_Object<ACE_Recursive_Thread_Mutex>
# pragma instantiate ACE_Managed_Object<ACE_Thread_Mutex>
# endif /* ACE_MT_SAFE */
diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h
index ad407c4da51..e43af1123ca 100644
--- a/ace/Object_Manager.h
+++ b/ace/Object_Manager.h
@@ -20,7 +20,9 @@
#include "ace/OS.h"
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ class ACE_Null_Mutex;
class ACE_Thread_Mutex;
+ class ACE_Recursive_Thread_Mutex;
#endif /* ACE_MT_SAFE */
// Forward declaration.
@@ -164,6 +166,9 @@ public:
ACE_DUMP_LOCK,
ACE_OS_MONITOR_LOCK,
ACE_SIG_HANDLER_LOCK,
+ ACE_SINGLETON_NULL_LOCK,
+ ACE_SINGLETON_RECURSIVE_THREAD_LOCK,
+ ACE_SINGLETON_THREAD_LOCK,
ACE_SVC_HANDLER_LOCK,
ACE_THREAD_EXIT_LOCK,
ACE_TOKEN_MANAGER_CREATION_LOCK,
@@ -197,13 +202,48 @@ public:
// ace/Managed_Object.h for information on accessing preallocated
// arrays.
+ static int starting_up ();
+ // 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_NON_STATIC_OBJECT_MANAGER is not
+ // defined.)
+
+ static int shutting_down ();
+ // 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_NON_STATIC_OBJECT_MANAGER is not defined.)
+
+private:
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+public:
+ // The get_singleton_lock accessors are for internal use by
+ // ACE_Singleton _only_. The arguments are ignored; they are
+ // only used for overload resolution.
+
+ static ACE_Null_Mutex *get_singleton_lock (ACE_Null_Mutex *);
+ // Accesses a null lock to be used for construction of ACE_Singletons.
+
+ static ACE_Thread_Mutex *get_singleton_lock (ACE_Thread_Mutex *);
+ // Accesses a non-recursve lock to be used for construction of
+ // ACE_Singletons.
+
+ static ACE_Recursive_Thread_Mutex *get_singleton_lock
+ (ACE_Recursive_Thread_Mutex *);
+ // Accesses a recursive lock to be used for construction of ACE_Singletons.
+
private:
+
+#endif /* ACE_MT_SAFE */
+
ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_;
// Keeps track of all registered objects.
- int shutting_down_;
- // Non-zero if this being destroyed
-
int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);
// Register an object or array for deletion at program termination.
// See description of static version above for return values.
@@ -211,10 +251,16 @@ private:
static ACE_Object_Manager *instance_;
// Singleton pointer.
+ static int starting_up_;
+ // Flag indicating whether the program is starting up.
+
+ static int shutting_down_;
+ // Flag indicating whether the program is shutting down.
+
public:
// For internal use only by ACE_Managed_Objects.
-# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
ACE_Thread_Mutex *lock_;
// Lock that is used to guard internal structures. Just a pointer
// is declared here in order to minimize the headers that this one
diff --git a/ace/Singleton.cpp b/ace/Singleton.cpp
index 6b098b29791..62a712d9388 100644
--- a/ace/Singleton.cpp
+++ b/ace/Singleton.cpp
@@ -19,9 +19,8 @@ ACE_Singleton<TYPE, ACE_LOCK>::dump (void)
ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::dump");
#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
- ACE_DEBUG ((LM_DEBUG, "instance_ = %x",
+ ACE_DEBUG ((LM_DEBUG, "instance_ = %x",
ACE_Singleton<TYPE, ACE_LOCK>::instance_i ()));
- ACE_Singleton<TYPE, ACE_LOCK>::singleton_lock_i ().dump ();
ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
}
@@ -40,40 +39,45 @@ ACE_Singleton<TYPE, ACE_LOCK>::instance_i (void)
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
}
-template <class TYPE, class ACE_LOCK> ACE_LOCK &
-ACE_Singleton<TYPE, ACE_LOCK>::singleton_lock_i (void)
-{
-#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
- // Lock the creation of the singleton. This works around a
- // "feature" of G++... ;-)
- static ACE_LOCK ace_singleton_lock_;
-
- return ace_singleton_lock_;
-#else
- return ACE_Singleton<TYPE, ACE_LOCK>::ace_singleton_lock_;
-#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
-}
-
template <class TYPE, class ACE_LOCK> TYPE *
ACE_Singleton<TYPE, ACE_LOCK>::instance (void)
{
ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::instance");
- ACE_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_Singleton<TYPE, ACE_LOCK> *&singleton =
ACE_Singleton<TYPE, ACE_LOCK>::instance_i ();
// Perform the Double-Check pattern...
if (singleton == 0)
{
- ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_Singleton<TYPE, ACE_LOCK>::singleton_lock_i ()), 0);
-
- if (singleton == 0)
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (ACE_Object_Manager::starting_up ())
{
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+#endif /* ACE_MT_SAFE */
ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
// Register for destruction with ACE_Object_Manager.
ACE_Object_Manager::at_exit (singleton);
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
}
+ else
+ {
+ // Use the Object_Manager's preallocated lock.
+ ACE_LOCK *lock =
+ ACE_Object_Manager::get_singleton_lock ((ACE_LOCK *) 0);
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ {
+ ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
+
+ // Register for destruction with ACE_Object_Manager.
+ ACE_Object_Manager::at_exit (singleton);
+ }
+ }
+#endif /* ACE_MT_SAFE */
}
return &singleton->instance_;
@@ -89,10 +93,6 @@ ACE_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
// Pointer to the Singleton instance.
template <class TYPE, class ACE_LOCK> ACE_Singleton<TYPE, ACE_LOCK> *
ACE_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
-
-// Lock the creation of the singleton.
-template <class TYPE, class ACE_LOCK> ACE_LOCK
-ACE_Singleton<TYPE, ACE_LOCK>::ace_singleton_lock_;
#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
template <class TYPE, class ACE_LOCK> void
@@ -101,63 +101,73 @@ ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump (void)
ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump");
#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
- ACE_DEBUG ((LM_DEBUG, "instance_ = %x", &singleton_->instance_));
- ace_singleton_lock_.dump();
+ ACE_DEBUG ((LM_DEBUG, "instance_ = %x",
+ ACE_Singleton<TYPE, ACE_LOCK>::instance_i ()));
ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
}
-template <class TYPE, class ACE_LOCK> TYPE *
-ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
+template <class TYPE, class ACE_LOCK> ACE_TSS_Singleton<TYPE, ACE_LOCK> *&
+ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i (void)
{
- ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance");
-
#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
// Pointer to the Singleton instance. This works around a bug with
- // G++...
+ // G++ and it's (mis-)handling of templates and statics...
static ACE_TSS_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;
- // Lock the creation of the singleton. This works around a
- // "feature" of G++... ;-)
- static ACE_LOCK ace_singleton_lock_;
+ return singleton_;
+#else
+ return ACE_TSS_Singleton<TYPE, ACE_LOCK>::singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TYPE *
+ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
+{
+ ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance");
- // Perform the Double-Check pattern...
- if (singleton_ == 0)
- {
- ACE_GUARD_RETURN (ACE_LOCK, ace_mon, ace_singleton_lock_, 0);
+ ACE_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
- if (singleton_ == 0)
+ // Perform the Double-Check pattern...
+ if (singleton == 0)
+ {
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (ACE_Object_Manager::starting_up ())
{
- ACE_NEW_RETURN (singleton_, (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+#endif /* ACE_MT_SAFE */
+ ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
#if 0 /* ACE_Object_Manager::at_thread_exit () is not implemented yet. */
// Register for destruction with ACE_Object_Manager.
- ACE_Object_Manager::at_thread_exit (instance_);
+ ACE_Object_Manager::at_thread_exit (singleton);
#endif /* 0 */
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
}
- }
-
-#else
-
- // Perform the Double-Check pattern...
- if (singleton_ == 0)
- {
- ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_TSS_Singleton<TYPE, ACE_LOCK>::ace_singleton_lock_), 0);
-
- if (singleton_ == 0)
+ else
{
- ACE_NEW_RETURN (singleton_, (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
+ // Use the Object_Manager's preallocated lock.
+ ACE_LOCK *lock =
+ ACE_Object_Manager::get_singleton_lock ((ACE_LOCK *) 0);
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ {
+ ACE_NEW_RETURN (singleton,
+ (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
#if 0 /* ACE_Object_Manager::at_thread_exit () is not implemented yet. */
- // Register for destruction with ACE_Object_Manager.
- ACE_Object_Manager::at_thread_exit (instance_);
+ // Register for destruction with ACE_Object_Manager.
+ ACE_Object_Manager::at_thread_exit (singleton);
#endif /* 0 */
+ }
}
+#endif /* ACE_MT_SAFE */
}
-#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
-
- return ACE_TSS_GET (&singleton_->instance_, TYPE);
+ return ACE_TSS_GET (&singleton->instance_, TYPE);
}
template <class TYPE, class ACE_LOCK> void
@@ -172,10 +182,6 @@ ACE_TSS_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
// Pointer to the Singleton instance.
template <class TYPE, class ACE_LOCK> ACE_TSS_Singleton <TYPE, ACE_LOCK> *
ACE_TSS_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
-
-// Lock the creation of the singleton.
-template <class TYPE, class ACE_LOCK> ACE_LOCK
-ACE_TSS_Singleton<TYPE, ACE_LOCK>::ace_singleton_lock_;
#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
#endif /* ACE_SINGLETON_C */
diff --git a/ace/Singleton.h b/ace/Singleton.h
index 034c2ee2ae7..7b40bd353d5 100644
--- a/ace/Singleton.h
+++ b/ace/Singleton.h
@@ -61,16 +61,10 @@ protected:
#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
static ACE_Singleton<TYPE, ACE_LOCK> *singleton_;
// Pointer to the Singleton (ACE_Cleanup) instance.
-
- static ACE_LOCK ace_singleton_lock_;
- // Lock the creation of the singleton.
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
// Get pointer to the Singleton instance.
-
- static ACE_LOCK &singleton_lock_i (void);
- // Get reference to Singleton lock.
};
template <class TYPE, class ACE_LOCK>
@@ -79,7 +73,7 @@ class ACE_TSS_Singleton : public ACE_Cleanup
// This class uses the Adapter pattern to turn ordinary classes
// into Thread-specific Singletons optimized with the
// Double-Checked Locking optimization pattern.
- //
+ //
// = DESCRIPTION
// This implementation is another variation on the GoF Singleton
// pattern. In this case, a single <ACE_TSS_Singleton<TYPE,
@@ -113,10 +107,10 @@ protected:
#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
static ACE_TSS_Singleton<TYPE, ACE_LOCK> *singleton_;
// Pointer to the Singleton (ACE_Cleanup) instance.
-
- static ACE_LOCK ace_singleton_lock_;
- // Lock the creation of the singleton.
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ static ACE_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+ // Get pointer to the TSS Singleton instance.
};
#if defined (__ACE_INLINE__)