/// \file This file contains the definitions of the template classes LockedSingleton and LockedSingletonWithDetor /// /// This file contains the definitions of the template classes LockedSingleton and LockedSingletonWithDetor. If a singleton class is defined in a dll then the macro THREADSAFEDLL should be defined, and the member boost::mutex LockedSingleton< Singleton>::Mutex should also be defined in that same dll. That way the Mutex is in the same linkage unit as the data which it protects. #ifndef THREADSAFE_H #define THREADSAFE_H #if defined( WIN32) && !defined(__NT__) #define __NT__ #endif #if defined( __NT__) && !defined(WIN32) #define WIN32 #endif #if defined(ALLSTATIC) && defined(THREADSAFEDLL) #error ALLSTATIC and THREADSAFEDLL are mutually exclusive #endif #if defined(ALLSTATIC) && defined(THREADSAFEDLL) #error ALLSTATIC and THREADSAFEDLL are mutually exclusive #endif #if defined(ALLSTATIC) || defined(THREADSAFESTATIC) #undef THREADSAFEPTR #define THREADSAFEPTR #define THREADSAFEFNC #elif !defined(THREADSAFEPTR) #ifdef __NT__ #ifdef THREADSAFEDLL #define THREADSAFEPTR __declspec(dllexport) #define THREADSAFEFNC __declspec(dllexport) #else #define THREADSAFEPTR __declspec(dllimport) #define THREADSAFEFNC __declspec(dllimport) #endif #else #define THREADSAFEFNC #define THREADSAFEPTR #endif #endif #ifdef __GNUC__ #ifdef THREADSAFEFNC #undef THREADSAFEFNC #endif #define THREADSAFEFNC #endif #ifdef WIN32 #define STDCALL __stdcall #else #define STDCALL #endif #include "boost/thread/thread.hpp" #include "boost/smart_ptr.hpp" /// \class LockedSingleton /// /// \brief This class takes a singleton class and adds a mutex to guarantee that all access to the singleton object is thread safe. /// /// Assumes:
  1. class Singleton has a function: "static Singleton* get_instance()";
  2. ///
  3. class Singleton does not destroy the single instance of this class
  4. ///
  5. class Singleton has its static variables declared in a source file
  6. ///
  7. The variable boost::mutex LockedSingleton< Singleton>::Mutex is declared in a source file
  8. ///
/// Description: This class takes a singleton class, "Singleton", and makes a new class, "LockedSingleton< Singleton>". //// This new class uses the boost thread library, and shared_ptr library. The new class requires its own mutex, /// "boost::mutex LockedSingleton< Singleton>::Mutex" to be declared and compiled in a source file. /// The static function get_instance, in the new class, returns a shared_ptr which references LockedSingleton< Singleton>, and which /// also locks Mutex. The Mutex is automatically unlocked when all references to the shared_ptr, go out of scope, and the /// destructor, "~LockedSingleton", is called template < typename Singleton> class THREADSAFEPTR LockedSingleton { protected: Singleton* _instance; boost::mutex::scoped_lock *point_lock; static boost::mutex Mutex; LockedSingleton( boost::mutex& Mutex) { point_lock = new boost::mutex::scoped_lock( Mutex); } public: static boost::shared_ptr< LockedSingleton > get_instance() { boost::shared_ptr< LockedSingleton> Instance( new LockedSingleton( Mutex)); Instance.get()->_instance = Singleton::get_instance(); return Instance; } Singleton* get () { return _instance; } ~LockedSingleton() { delete point_lock; } }; /// \class LockedSingletonWithDetor /// /// \brief This class takes a singleton class, that has a destructor, and adds a mutex to guarantee that all access to the singleton object is thread safe, including the destruction of the object. /// /// Assumes:
    all of the assumptions as class LockedSingleton:
      ///
    1. class Singleton has a function: "static Singleton* get_instance()";
    2. ///
    3. class Singleton does not destroy the single instance of this class
    4. ///
    5. class Singleton has its static variables declared in a source file
    6. ///
    7. The varialbe boost::mutex LockedSingleton< Singleton>::Mutex is declared in a source file
    8. ///
    ///
  1. class Singleton has a function "static void destroy_instance()" which destroys the its single instance
  2. ///
/// Description: This class is a child class of class LockedSingleton. The description of class locked singleton, therefore applies /// to this class also: ///

This class takes a singleton class, "Singleton", and makes a new class, "LockedSingleton< Singleton>". //// This new class uses the boost thread library, and shared_ptr library. The new class requires its own mutex, /// "boost::mutex LockedSingleton< Singleton>::Mutex" to be declared and compiled in a source file. /// The static function get_instance, in the new class, returns a shared_ptr which references LockedSingleton< Singleton>, and which /// also locks Mutex. The Mutex is automatically unlocked when all references to the shared_ptr, go out of scope, and the /// destructor, "~LockedSingleton", is called. ///

///

In addition the new class LockedSingletonWithDetor has a static function, "static void destroy_instance()", which destroys /// the single instance of class Singleton, in a thread safe way.

template< typename Singleton> class THREADSAFEPTR LockedSingletonWithDetor : public LockedSingleton< Singleton> { LockedSingletonWithDetor( boost::mutex& Mutex) : LockedSingleton< Singleton> ( Mutex) { } public: static boost::shared_ptr< LockedSingletonWithDetor > get_instance() { boost::shared_ptr< LockedSingletonWithDetor< Singleton> > Instance( new LockedSingletonWithDetor< Singleton>( Mutex)); Instance.get()->_instance = Singleton::get_instance(); return Instance; } static void destroy_instance() { boost::mutex::scoped_lock freeze( Mutex); Singleton::destroy_instance(); } }; #endif