/* -*- C++ -*- */ //============================================================================= /** * @file Singleton.h * * $Id$ * * @brief * * @author Tim Harrison , * Douglas C. Schmidt , * Chris Lahey, * Rich Christy, and * David Levine . */ //============================================================================= #ifndef ACE_SINGLETON_H #define ACE_SINGLETON_H #include "ace/pre.h" #include "ace/Synch.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ /** * @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 * > instance is allocated here, * not a instance. The reason for this is to allow * registration with the , so that the * Singleton can be cleaned up when the process exits. For this * scheme to work, a (static) function must be * provided. provides one so that TYPE doesn't * need to. * If you want to make sure that only the singleton instance of * is created, and that users cannot create their own * instances of , do the following to class : * (a) Make the constructor of private (or protected) * (b) Make Singleton a friend of * Here is an example: * @verbatim * class foo * { * friend class ACE_Singleton; * private: * foo () { cout << "foo constructed" << endl; } * ~foo () { cout << "foo destroyed" << endl; } * }; * typedef ACE_Singleton 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 > 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 ACE_Singleton : public ACE_Cleanup { public: /// Global access point to the Singleton. static TYPE *instance (void); /// Cleanup method, used by to destroy the /// . 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 *singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ /// Get pointer to the Singleton instance. static ACE_Singleton *&instance_i (void); }; /** * @class ACE_Unmanaged_Singleton * * @brief Same as , except does _not_ register with * for destruction. * * This version of can be used if, for example, * its DLL will be unloaded before the * destroys the instance. Unlike with , 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 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*, not an ACE_Unmanaged_Singleton. */ template class ACE_Unmanaged_Singleton : public ACE_Singleton { 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 *singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ /// Get pointer to the Singleton instance. static ACE_Unmanaged_Singleton *&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 > instance is allocated here, not a instance. * Each call to the static method returns a Singleton * whose pointer resides in thread-specific storage. As with * , we use the so that the * Singleton can be cleaned up when the process exits. For this * scheme to work, a (static) function must be * provided. provides one so that TYPE doesn't * need to. */ template class ACE_TSS_Singleton : public ACE_Cleanup { public: /// Global access point to the Singleton. static TYPE *instance (void); /// Cleanup method, used by 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 &)) ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Singleton (const ACE_TSS_Singleton &)) #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) /// Pointer to the Singleton (ACE_Cleanup) instance. static ACE_TSS_Singleton *singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ /// Get pointer to the TSS Singleton instance. static ACE_TSS_Singleton *&instance_i (void); }; /** * @class ACE_Unmanaged_TSS_Singleton * * @brief Same as , except does _not_ register with * for destruction. * * This version of can be used if, for * example, its DLL will be unloaded before the * destroys the instance. Unlike with * , 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 * static member function must be used to explicitly * destroy the Singleton. */ template class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton { 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 *singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ /// Get pointer to the Singleton instance. static ACE_Unmanaged_TSS_Singleton *&instance_i (void); }; /** * @class ACE_DLL_Singleton_T * * @brief Same as , except that it registers for * destruction with the instead of * with the directly. * * This version of 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 * below for a convenient example of how to satisfy this * requirement for the dll_name(). * * Usage is the same as for , but note that if you * you declare a friend, the friend class must still be an * *ACE_Singleton*, not an ACE_Unmanaged_Singleton. */ template 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 *singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ /// Get pointer to the Singleton instance. static ACE_DLL_Singleton_T *&instance_i (void); }; template class ACE_DLL_Singleton_Adapter_T : public TYPE { public: const ACE_TCHAR *dll_name (void); }; #if defined (__ACE_INLINE__) #include "ace/Singleton.i" #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 */