Changeset abab7e for molecuilder/src


Ignore:
Timestamp:
Mar 11, 2010, 11:32:17 AM (15 years ago)
Author:
Tillmann Crueger <crueger@…>
Children:
8a4f12
Parents:
ff1812
Message:

Changed the mutex type used in the Singleton pattern to allow multiple locks in the same thread

Location:
molecuilder/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/Patterns/Singleton.hpp

    rff1812 rabab7e  
    8787
    8888private:
    89   static boost::mutex instanceLock;
     89  static boost::recursive_mutex instanceLock;
    9090  static ptr_t theInstance;
    9191};
  • molecuilder/src/Patterns/Singleton_impl.hpp

    rff1812 rabab7e  
    1010
    1111#include "Patterns/Singleton.hpp"
     12
     13/****** Static instance Variables of the template *******/
     14
     15template <class T,bool _may_create>
     16typename Singleton<T,_may_create>::ptr_t Singleton<T,_may_create>::theInstance(0);
     17
     18template <class T,bool _may_create>
     19boost::recursive_mutex Singleton<T,_may_create>::instanceLock;
     20
     21/****** templates singleton creation and destruction functions ******/
     22
     23template <class T,bool _may_create>
     24T& Singleton<T,_may_create>::getInstance(){
     25  // boost supports RAII-Style locking, so we don't need to unlock
     26  boost::recursive_mutex::scoped_lock guard(instanceLock);
     27  if(!theInstance.get()) {
     28    theInstance.reset(creator::make());
     29  }
     30  return *theInstance;
     31}
     32
     33template <class T,bool _may_create>
     34T* Singleton<T,_may_create>::getPointer(){
     35  // boost supports RAII-Style locking, so we don't need to unlock
     36  boost::recursive_mutex::scoped_lock guard(instanceLock);
     37  if(!theInstance.get()) {
     38    theInstance.reset(creator::make());
     39  }
     40  return theInstance.get();
     41
     42}
     43
     44template <class T,bool _may_create>
     45void Singleton<T,_may_create>::purgeInstance(){
     46  // boost supports RAII-Style locking, so we don't need to unlock
     47  boost::recursive_mutex::scoped_lock guard(instanceLock);
     48  theInstance.reset();
     49}
     50
     51template <class T,bool _may_create>
     52T& Singleton<T,_may_create>::resetInstance(){
     53  ptr_t oldInstance;
     54  {
     55    // boost supports RAII-Style locking, so we don't need to unlock
     56    boost::recursive_mutex::scoped_lock guard(instanceLock);
     57
     58    oldInstance = theInstance;
     59    theInstance.reset(creator::make());
     60    // oldworld does not need protection any more,
     61    // since we should have the only reference
     62
     63    // worldLock handles access to the pointer,
     64    // not to the object
     65  } // scope-end releases the lock
     66
     67  // oldInstance goes out of scope at the End of this function. The carried object will then be destroyed by the auto_ptr
     68  return *theInstance;
     69}
     70
     71
     72template <class T,bool _may_create>
     73void Singleton<T,_may_create>::setInstance(T* newInstance){
     74  assert(!theInstance.get() && "Trying to set the instance of an already created singleton");
     75  boost::recursive_mutex::scoped_lock guard(instanceLock);
     76  theInstance.reset(newInstance);
     77}
     78
     79/**
     80 * This define allows simple instantiation of the necessary singleton functions
     81 * at a chosen place.
     82 */
     83#define CONSTRUCT_SINGLETON(name) \
     84    template name& Singleton< name , name::may_create >::getInstance(); \
     85    template name* Singleton< name , name::may_create >::getPointer();  \
     86    template void  Singleton< name , name::may_create >::purgeInstance(); \
     87    template name& Singleton< name , name::may_create >::resetInstance(); \
     88    template void  Singleton< name , name::may_create >::setInstance( name* );
     89
     90/************ Internal Pointer Wrapper to allow automatic purging *************/
    1291
    1392template <class T,bool _may_create>
     
    51130}
    52131
    53 template <class T,bool _may_create>
    54 typename Singleton<T,_may_create>::ptr_t Singleton<T,_may_create>::theInstance(0);
    55 
    56 template <class T,bool _may_create>
    57 boost::mutex Singleton<T,_may_create>::instanceLock;
    58 
    59 template <class T,bool _may_create>
    60 T& Singleton<T,_may_create>::getInstance(){
    61   // boost supports RAII-Style locking, so we don't need to unlock
    62   boost::mutex::scoped_lock guard(instanceLock);
    63   if(!theInstance.get()) {
    64     theInstance.reset(creator::make());
    65   }
    66   return *theInstance;
    67 }
    68 
    69 template <class T,bool _may_create>
    70 T* Singleton<T,_may_create>::getPointer(){
    71   // boost supports RAII-Style locking, so we don't need to unlock
    72   boost::mutex::scoped_lock guard(instanceLock);
    73   if(!theInstance.get()) {
    74     theInstance.reset(creator::make());
    75   }
    76   return theInstance.get();
    77 
    78 }
    79 
    80 template <class T,bool _may_create>
    81 void Singleton<T,_may_create>::purgeInstance(){
    82   // boost supports RAII-Style locking, so we don't need to unlock
    83   boost::mutex::scoped_lock guard(instanceLock);
    84   theInstance.reset();
    85 }
    86 
    87 template <class T,bool _may_create>
    88 T& Singleton<T,_may_create>::resetInstance(){
    89   ptr_t oldInstance;
    90   {
    91     // boost supports RAII-Style locking, so we don't need to unlock
    92     boost::mutex::scoped_lock guard(instanceLock);
    93 
    94     oldInstance = theInstance;
    95     theInstance.reset(creator::make());
    96     // oldworld does not need protection any more,
    97     // since we should have the only reference
    98 
    99     // worldLock handles access to the pointer,
    100     // not to the object
    101   } // scope-end releases the lock
    102 
    103   // oldInstance goes out of scope at the End of this function. The carried object will then be destroyed by the auto_ptr
    104   return *theInstance;
    105 }
    106 
    107 
    108 template <class T,bool _may_create>
    109 void Singleton<T,_may_create>::setInstance(T* newInstance){
    110   assert(!theInstance.get() && "Trying to set the instance of an already created singleton");
    111   boost::mutex::scoped_lock guard(instanceLock);
    112   theInstance.reset(newInstance);
    113 }
    114 
    115 #define CONSTRUCT_SINGLETON(name) \
    116     template name& Singleton< name , name::may_create >::getInstance(); \
    117     template name* Singleton< name , name::may_create >::getPointer();  \
    118     template void  Singleton< name , name::may_create >::purgeInstance(); \
    119     template name& Singleton< name , name::may_create >::resetInstance(); \
    120     template void  Singleton< name , name::may_create >::setInstance( name* );
    121132
    122133#endif /* SINGLETON_IMPL_HPP_ */
  • molecuilder/src/unittests/Makefile.am

    rff1812 rabab7e  
    2828  MoleculeDescriptorTest \
    2929  ObserverTest \
     30  SingletonTest \
    3031  StackClassUnitTest \
    3132  TesselationUnitTest \
     
    6768  MoleculeDescriptorTest.cpp \
    6869  ObserverTest.cpp \
     70  SingletonTest.cpp \
    6971  stackclassunittest.cpp \
    7072  tesselationunittest.cpp \
     
    124126MoleculeDescriptorTest_LDADD = ${ALLLIBS}
    125127
     128SingletonTest_SOURCES = UnitTestMain.cpp SingletonTest.cpp SingletonTest.hpp
     129SingletonTest_LDADD = $(BOOST_LIB) ${BOOST_THREAD_LIB}
     130
    126131StackClassUnitTest_SOURCES = UnitTestMain.cpp stackclassunittest.cpp stackclassunittest.hpp
    127132StackClassUnitTest_LDADD = ${ALLLIBS}
  • molecuilder/src/unittests/atomsCalculationTest.cpp

    rff1812 rabab7e  
    2323#include "World_calculations.hpp"
    2424#include "atom.hpp"
     25
     26#ifdef HAVE_TESTRUNNER
     27#include "UnitTestMain.hpp"
     28#endif /*HAVE_TESTRUNNER*/
    2529
    2630// Registers the fixture into the 'registry'
  • molecuilder/src/unittests/manipulateAtomsTest.cpp

    rff1812 rabab7e  
    2121#include "World.hpp"
    2222#include "atom.hpp"
     23
     24#ifdef HAVE_TESTRUNNER
     25#include "UnitTestMain.hpp"
     26#endif /*HAVE_TESTRUNNER*/
    2327
    2428// Registers the fixture into the 'registry'
Note: See TracChangeset for help on using the changeset viewer.