summaryrefslogtreecommitdiff
path: root/trunk/ACE/ace/Singleton.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ACE/ace/Singleton.h')
-rw-r--r--trunk/ACE/ace/Singleton.h327
1 files changed, 327 insertions, 0 deletions
diff --git a/trunk/ACE/ace/Singleton.h b/trunk/ACE/ace/Singleton.h
new file mode 100644
index 00000000000..032f26740f4
--- /dev/null
+++ b/trunk/ACE/ace/Singleton.h
@@ -0,0 +1,327 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Singleton.h
+ *
+ * $Id$
+ *
+ * @brief
+ *
+ * @author Tim Harrison <harrison@cs.wustl.edu>
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Chris Lahey
+ * @author Rich Christy
+ * @author David Levine <levine@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_SINGLETON_H
+#define ACE_SINGLETON_H
+#include /**/ "ace/pre.h"
+
+#include /**/ "ace/config-all.h"
+#include "ace/TSS_T.h"
+#include "ace/Cleanup.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Singleton
+ *
+ * @brief A Singleton Adapter uses the Adapter pattern to turn ordinary
+ * classes into Singletons optimized with the Double-Checked
+ * Locking optimization pattern.
+ *
+ * This implementation is a slight variation on the GoF
+ * Singleton pattern. In particular, a single
+ * <ACE_Singleton<TYPE, ACE_LOCK> > instance is allocated here,
+ * not a <TYPE> instance. The reason for this is to allow
+ * registration with the ACE_Object_Manager, so that the
+ * Singleton can be cleaned up when the process exits. For this
+ * scheme to work, a (static) cleanup() function must be
+ * provided. ACE_Singleton provides one so that TYPE doesn't
+ * need to.
+ * If you want to make sure that only the singleton instance of
+ * <T> is created, and that users cannot create their own
+ * instances of <T>, do the following to class <T>:
+ * (a) Make the constructor of <T> private (or protected)
+ * (b) Make Singleton a friend of <T>
+ * Here is an example:
+ * @verbatim
+ * class foo
+ * {
+ * friend class ACE_Singleton<foo, ACE_Null_Mutex>;
+ * private:
+ * foo () { cout << "foo constructed" << endl; }
+ * ~foo () { cout << "foo destroyed" << endl; }
+ * };
+ * typedef ACE_Singleton<foo, ACE_Null_Mutex> FOO;
+ * @endverbatim
+ *
+ * @note The best types to use for ACE_LOCK are
+ * ACE_Recursive_Thread_Mutex and ACE_Null_Mutex.
+ * ACE_Recursive_Thread_Mutex should be used in multi-threaded
+ * programs in which it is possible for more than one thread to
+ * access the <ACE_Singleton<TYPE, ACE_LOCK>> instance.
+ * ACE_Null_Mutex can be used otherwise. The reason that these
+ * types of locks are best has to do with their allocation by
+ * the ACE_Object_Manager. Single ACE_Recursive_Thread_Mutex
+ * and ACE_Null_Mutex instances are used for all ACE_Singleton
+ * instantiations. However, other types of locks are allocated
+ * per ACE_Singleton instantiation.
+ */
+template <class TYPE, class ACE_LOCK>
+class ACE_Singleton : public ACE_Cleanup
+{
+public:
+ /// Global access point to the Singleton.
+ static TYPE *instance (void);
+
+ /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the
+ /// ACE_Singleton.
+ virtual void cleanup (void *param = 0);
+
+ /// Dump the state of the object.
+ static void dump (void);
+
+protected:
+ /// Default constructor.
+ ACE_Singleton (void);
+
+ /// Contained instance.
+ TYPE instance_;
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ /// Pointer to the Singleton (ACE_Cleanup) instance.
+ static ACE_Singleton<TYPE, ACE_LOCK> *singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ /// Get pointer to the Singleton instance.
+ static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+};
+
+/**
+ * @class ACE_Unmanaged_Singleton
+ *
+ * @brief Same as ACE_Singleton, except does _not_ register with
+ * ACE_Object_Manager for destruction.
+ *
+ * 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.
+ * Usage is the same as for ACE_Singleton, but note that if you
+ * you declare a friend, the friend class must still be an
+ * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton.
+ */
+template <class TYPE, class ACE_LOCK>
+class ACE_Unmanaged_Singleton : public ACE_Singleton <TYPE, ACE_LOCK>
+{
+public:
+ /// Global access point to the Singleton.
+ static TYPE *instance (void);
+
+ /// Explicitly delete the Singleton instance.
+ static void close (void);
+
+ /// Dump the state of the object.
+ static void dump (void);
+
+protected:
+ /// Default constructor.
+ ACE_Unmanaged_Singleton (void);
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ /// Pointer to the Singleton (ACE_Cleanup) instance.
+ static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ /// Get pointer to the Singleton instance.
+ static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+};
+
+/**
+ * @class ACE_TSS_Singleton
+ *
+ * @brief This class uses the Adapter pattern to turn ordinary classes
+ * into Thread-specific Singletons optimized with the
+ * Double-Checked Locking optimization pattern.
+ *
+ * This implementation is another variation on the GoF Singleton
+ * pattern. In this case, a single <ACE_TSS_Singleton<TYPE,
+ * LOCK> > instance is allocated here, not a <TYPE> instance.
+ * Each call to the <instance> static method returns a Singleton
+ * whose pointer resides in thread-specific storage. As with
+ * ACE_Singleton, we use the ACE_Object_Manager so that the
+ * Singleton can be cleaned up when the process exits. For this
+ * scheme to work, a (static) cleanup() function must be
+ * provided. ACE_Singleton provides one so that TYPE doesn't
+ * need to.
+ */
+template <class TYPE, class ACE_LOCK>
+class ACE_TSS_Singleton : public ACE_Cleanup
+{
+public:
+ /// Global access point to the singleton.
+ static TYPE *instance (void);
+
+ /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the
+ /// singleton.
+ virtual void cleanup (void *param = 0);
+
+ /// Dump the state of the object.
+ static void dump (void);
+
+protected:
+ /// Default constructor.
+ ACE_TSS_Singleton (void);
+
+ /// Contained instance.
+ ACE_TSS_TYPE (TYPE) instance_;
+
+ ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &))
+ ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Singleton (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &))
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ /// Pointer to the Singleton (ACE_Cleanup) instance.
+ static ACE_TSS_Singleton<TYPE, ACE_LOCK> *singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ /// Get pointer to the TSS Singleton instance.
+ static ACE_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+};
+
+/**
+ * @class ACE_Unmanaged_TSS_Singleton
+ *
+ * @brief Same as ACE_TSS_Singleton, except does _not_ register with
+ * ACE_Object_Manager for destruction.
+ *
+ * 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.
+ */
+template <class TYPE, class ACE_LOCK>
+class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton <TYPE, ACE_LOCK>
+{
+public:
+ /// Global access point to the singleton.
+ static TYPE *instance (void);
+
+ /// Explicitly delete the singleton instance.
+ static void close (void);
+
+ /// Dump the state of the object.
+ static void dump (void);
+
+protected:
+ /// Default constructor.
+ ACE_Unmanaged_TSS_Singleton (void);
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ /// Pointer to the Singleton (ACE_Cleanup) instance.
+ static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ /// Get pointer to the Singleton instance.
+ static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
+};
+
+/**
+ * @class ACE_DLL_Singleton_T
+ *
+ * @brief Same as ACE_Singleton, except that it registers for
+ * destruction with the ACE_Framework_Repository instead of
+ * with the ACE_Object_Manager directly.
+ *
+ * This version of ACE_Singleton should be used for singletons
+ * that live in a dll loaded either directly by ACE_DLL or indirectly
+ * by the ACE Service Configuration framework. Whenever ACE_DLL is ready
+ * to actually unload the dll, ACE_DLL_Singleton based dlls associated
+ * with that dll will be destroyed first. In fact, any singleton can
+ * safely use ACE_DLL_Singleton, even those that don't live in dlls. In
+ * that case, the singleton will be destroyed at normal program shutdown.
+ *
+ * The only additional requirement is that the contained class
+ * export name() and dll_name() methods. See ACE_DLL_Singleton_Adapter_T
+ * below for a convenient example of how to satisfy this
+ * requirement for the dll_name().
+ *
+ * Usage is the same as for ACE_Singleton, but note that if you
+ * you declare a friend, the friend class must still be an
+ * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton.
+ */
+template <class TYPE, class ACE_LOCK>
+class ACE_DLL_Singleton_T
+{
+public:
+ //void cleanup (void *param = 0);
+
+ /// Global access point to the Singleton.
+ static TYPE *instance (void);
+
+ /// Explicitly delete the Singleton instance.
+ static void close (void);
+
+ static void close_singleton (void);
+
+ /// Dump the state of the object.
+ static void dump (void);
+
+ const ACE_TCHAR *dll_name (void);
+
+ const ACE_TCHAR *name (void);
+
+protected:
+ /// Default constructor.
+ ACE_DLL_Singleton_T (void);
+
+ /// Destructor.
+ ~ACE_DLL_Singleton_T (void);
+
+ /// Contained instance.
+ TYPE instance_;
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ /// Pointer to the Singleton instance.
+ static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *singleton_;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+ /// Get pointer to the singleton instance.
+ static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&instance_i (void);
+};
+
+template <class TYPE>
+class ACE_DLL_Singleton_Adapter_T : public TYPE
+{
+public:
+ const ACE_TCHAR *dll_name (void);
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+#include "ace/Singleton.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Singleton.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Singleton.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SINGLETON_H */