summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-07-14 15:25:12 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-07-14 15:25:12 +0000
commit04a062314bfcda6a53204bbddf9ad9c579fa3126 (patch)
tree043c42056ea2704243da8004289676889abb1eba /ace
parent7986e98bcc4960a30e97ea92c3a7eb157581364f (diff)
downloadATCD-04a062314bfcda6a53204bbddf9ad9c579fa3126.tar.gz
ChangeLogTag: Wed Jul 14 10:22:29 1999 David L. Levine <levine@cs.wustl.edu>
Diffstat (limited to 'ace')
-rw-r--r--ace/Singleton.cpp201
-rw-r--r--ace/Singleton.h79
-rw-r--r--ace/Singleton.i11
3 files changed, 276 insertions, 15 deletions
diff --git a/ace/Singleton.cpp b/ace/Singleton.cpp
index 6dc4def40c4..4aaf6be5e14 100644
--- a/ace/Singleton.cpp
+++ b/ace/Singleton.cpp
@@ -68,9 +68,7 @@ ACE_Singleton<TYPE, ACE_LOCK>::instance (void)
// ACE_Object_Manager: we'll have to leak this instance.
#endif /* ACE_MT_SAFE */
- ACE_NEW_RETURN (singleton,
- (ACE_Singleton<TYPE,
- ACE_LOCK>), 0);
+ ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
}
else
@@ -87,9 +85,8 @@ ACE_Singleton<TYPE, ACE_LOCK>::instance (void)
if (singleton == 0)
{
- ACE_NEW_RETURN (singleton,
- (ACE_Singleton<TYPE, ACE_LOCK>),
- 0);
+ ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
+
// Register for destruction with ACE_Object_Manager.
ACE_Object_Manager::at_exit (singleton);
}
@@ -111,9 +108,99 @@ 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;
+
+template <class TYPE, class ACE_LOCK> ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
template <class TYPE, class ACE_LOCK> void
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::dump (void)
+{
+ ACE_TRACE ("ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::dump");
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("instance_ = %x"),
+ ACE_Unmanaged_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>
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i (void)
+{
+#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ // Pointer to the Singleton instance. This works around a bug with
+ // G++ and it's (mis-)handling of templates and statics...
+ static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;
+
+ return singleton_;
+#else
+ return ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TYPE *
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance (void)
+{
+ ACE_TRACE ("ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance");
+
+ ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ // Perform the Double-Check pattern...
+ if (singleton == 0)
+ {
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (ACE_Object_Manager::starting_up () ||
+ ACE_Object_Manager::shutting_down ())
+ {
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+ // Or, the ACE_Object_Manager instance has been destroyed,
+ // so the preallocated lock is not available. Either way,
+ // don't register for destruction with the
+ // ACE_Object_Manager: we'll have to leak this instance.
+#endif /* ACE_MT_SAFE */
+
+ ACE_NEW_RETURN (singleton, (ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>),
+ 0);
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ }
+ else
+ {
+ // Obtain a lock from the ACE_Object_Manager. The pointer
+ // is static, so we only obtain one per
+ // ACE_Unmanaged_Singleton instantiation.
+ static ACE_LOCK *lock = 0;
+ if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
+ // Failed to acquire the lock!
+ return 0;
+
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ ACE_NEW_RETURN (singleton,
+ (ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>),
+ 0);
+ }
+#endif /* ACE_MT_SAFE */
+ }
+
+ return &singleton->instance_;
+}
+
+template <class TYPE, class ACE_LOCK> void
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::close (void)
+{
+ ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ if (singleton)
+ singleton->cleanup ();
+}
+
+template <class TYPE, class ACE_LOCK> void
ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump (void)
{
ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump");
@@ -161,9 +248,8 @@ ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
// don't register for destruction with the
// ACE_Object_Manager: we'll have to leak this instance.
#endif /* ACE_MT_SAFE */
- ACE_NEW_RETURN (singleton,
- (ACE_TSS_Singleton<TYPE, ACE_LOCK>),
- 0);
+
+ ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
}
else
@@ -179,9 +265,9 @@ ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
if (singleton == 0)
{
- ACE_NEW_RETURN (singleton,
- (ACE_TSS_Singleton<TYPE, ACE_LOCK>),
+ ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton<TYPE, ACE_LOCK>),
0);
+
// Register for destruction with ACE_Object_Manager.
ACE_Object_Manager::at_exit (singleton);
}
@@ -195,16 +281,105 @@ ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
template <class TYPE, class ACE_LOCK> void
ACE_TSS_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
{
- ACE_TRACE ("ACE_TSS_Singleton::cleanup");
-
delete this;
ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
}
+template <class TYPE, class ACE_LOCK> void
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::dump (void)
+{
+ ACE_TRACE ("ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::dump");
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("instance_ = %x"),
+ ACE_Unmanaged_TSS_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>
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i (void)
+{
+#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ // Pointer to the Singleton instance. This works around a bug with
+ // G++ and it's (mis-)handling of templates and statics...
+ static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;
+
+ return singleton_;
+#else
+ return ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template <class TYPE, class ACE_LOCK> TYPE *
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance (void)
+{
+ ACE_TRACE ("ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance");
+
+ ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ // Perform the Double-Check pattern...
+ if (singleton == 0)
+ {
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ if (ACE_Object_Manager::starting_up () ||
+ ACE_Object_Manager::shutting_down ())
+ {
+ // The program is still starting up, and therefore assumed
+ // to be single threaded. There's no need to double-check.
+ // Or, the ACE_Object_Manager instance has been destroyed,
+ // so the preallocated lock is not available. Either way,
+ // don't register for destruction with the
+ // ACE_Object_Manager: we'll have to leak this instance.
+#endif /* ACE_MT_SAFE */
+ ACE_NEW_RETURN (singleton,
+ (ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>),
+ 0);
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ }
+ else
+ {
+ // Obtain a lock from the ACE_Object_Manager. The pointer
+ // is static, so we only obtain one per
+ // ACE_Unmanaged_Singleton instantiation.
+ static ACE_LOCK *lock = 0;
+ if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
+ // Failed to acquire the lock!
+ return 0;
+
+ ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
+
+ if (singleton == 0)
+ ACE_NEW_RETURN (singleton,
+ (ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>),
+ 0);
+ }
+#endif /* ACE_MT_SAFE */
+ }
+
+ return ACE_TSS_GET (&singleton->instance_, TYPE);
+}
+
+template <class TYPE, class ACE_LOCK> void
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::close (void)
+{
+ ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
+ ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
+
+ if (singleton)
+ singleton->cleanup ();
+}
+
#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
// 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;
+
+template <class TYPE, class ACE_LOCK>
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
#endif /* ACE_SINGLETON_C */
diff --git a/ace/Singleton.h b/ace/Singleton.h
index 14bb6461ccb..9bef9acf126 100644
--- a/ace/Singleton.h
+++ b/ace/Singleton.h
@@ -104,6 +104,45 @@ protected:
};
template <class TYPE, class ACE_LOCK>
+class ACE_Unmanaged_Singleton : public ACE_Singleton <TYPE, ACE_LOCK>
+{
+ // = TITLE
+ // Same as <ACE_Singleton>, except does _not_ register with
+ // <ACE_Object_Manager> for destruction.
+ //
+ // = DESCRIPTION
+ // This version of <ACE_Singleton> can be used if, for example,
+ // its DLL will be unloaded before the <ACE_Object_Manager>
+ // destroys the instance. Unlike with <ACE_Singleton>, the
+ // application is responsible for explicitly destroying the
+ // instance after it is no longer needed (if it wants to avoid
+ // memory leaks, at least). The close () static member function
+ // must be used to explicitly destroy the Singleton.
+ //
+public:
+ static TYPE *instance (void);
+ // Global access point to the Singleton.
+
+ static void close (void);
+ // Explicitly delete the Singleton instance.
+
+ static void dump (void);
+ // Dump the state of the object.
+
+protected:
+ ACE_Unmanaged_Singleton (void);
+ // Default constructor.
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *singleton_;
+ // Pointer to the Singleton (ACE_Cleanup) instance.
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+ // Get pointer to the Singleton instance.
+};
+
+template <class TYPE, class ACE_LOCK>
class ACE_TSS_Singleton : public ACE_Cleanup
{
// = TITLE
@@ -149,6 +188,46 @@ protected:
// Get pointer to the TSS Singleton instance.
};
+template <class TYPE, class ACE_LOCK>
+class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton <TYPE, ACE_LOCK>
+{
+ // = TITLE
+ // Same as <ACE_TSS_Singleton>, except does _not_ register with
+ // <ACE_Object_Manager> for destruction.
+ //
+ // = DESCRIPTION
+ // This version of <ACE_TSS_Singleton> can be used if, for
+ // example, its DLL will be unloaded before the
+ // <ACE_Object_Manager> destroys the instance. Unlike with
+ // <ACE_Singleton>, the application is responsible for
+ // explicitly destroying the instance after it is no longer
+ // needed (if it wants to avoid memory leaks, at least). The
+ // close () static member function must be used to explicitly
+ // destroy the Singleton.
+ //
+public:
+ static TYPE *instance (void);
+ // Global access point to the Singleton.
+
+ static void close (void);
+ // Explicitly delete the Singleton instance.
+
+ static void dump (void);
+ // Dump the state of the object.
+
+protected:
+ ACE_Unmanaged_TSS_Singleton (void);
+ // Default constructor.
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *singleton_;
+ // Pointer to the Singleton (ACE_Cleanup) instance.
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+ // Get pointer to the Singleton instance.
+};
+
#if defined (__ACE_INLINE__)
#include "ace/Singleton.i"
#endif /* __ACE_INLINE__ */
diff --git a/ace/Singleton.i b/ace/Singleton.i
index c49bd5a0428..38e37fc3d7c 100644
--- a/ace/Singleton.i
+++ b/ace/Singleton.i
@@ -1,8 +1,6 @@
/* -*- C++ -*- */
// $Id$
-// Singleton.i
-
// Default constructors.
//
// Note: don't explicitly initialize "instance_", because TYPE may not
@@ -14,7 +12,16 @@ ACE_Singleton<TYPE, ACE_LOCK>::ACE_Singleton (void)
}
template <class TYPE, class ACE_LOCK> ACE_INLINE
+ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::ACE_Unmanaged_Singleton (void)
+{
+}
+
+template <class TYPE, class ACE_LOCK> ACE_INLINE
ACE_TSS_Singleton<TYPE, ACE_LOCK>::ACE_TSS_Singleton (void)
{
}
+template <class TYPE, class ACE_LOCK> ACE_INLINE
+ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::ACE_Unmanaged_TSS_Singleton (void)
+{
+}