mxw_wotlk_azerothcore/deps/acelite/ace/Singleton.h

329 lines
10 KiB
C++

// -*- C++ -*-
//=============================================================================
/**
* @file Singleton.h
*
* @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 @c ace_cleanup_destroyer to destroy the
/// ACE_Singleton.
virtual void cleanup (void *param = 0);
/// Explicitly delete the Singleton instance.
static void close (void);
/// 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 */