source: molecuilder/src/Patterns/Singleton_impl.hpp@ abab7e

Last change on this file since abab7e was abab7e, checked in by Tillmann Crueger <crueger@…>, 16 years ago

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

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 * Singleton_impl.hpp
3 *
4 * Created on: Mar 10, 2010
5 * Author: crueger
6 */
7
8#ifndef SINGLETON_IMPL_HPP_
9#define SINGLETON_IMPL_HPP_
10
11#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 *************/
91
92template <class T,bool _may_create>
93Singleton<T,_may_create>::ptr_t::ptr_t() :
94content(0){};
95
96template <class T,bool _may_create>
97Singleton<T,_may_create>::ptr_t::ptr_t(T* _content) :
98content(_content){};
99
100template <class T,bool _may_create>
101Singleton<T,_may_create>::ptr_t:: ~ptr_t()
102{delete content;};
103
104template <class T,bool _may_create>
105T& Singleton<T,_may_create>::ptr_t::operator*()
106{return *content;};
107
108template <class T,bool _may_create>
109T* Singleton<T,_may_create>::ptr_t::get()
110{return content;};
111
112template <class T,bool _may_create>
113void Singleton<T,_may_create>::ptr_t::reset(T* _content){
114 delete content;
115 content = _content;
116}
117
118template <class T,bool _may_create>
119void Singleton<T,_may_create>::ptr_t::reset()
120{reset(0);}
121
122template <class T,bool _may_create>
123typename Singleton<T,_may_create>::ptr_t& Singleton<T,_may_create>::ptr_t::operator=(typename Singleton<T,_may_create>::ptr_t& rhs){
124 if(&rhs!=this){
125 delete content;
126 content = rhs.content;
127 rhs.content = 0;
128 }
129 return *this;
130}
131
132
133#endif /* SINGLETON_IMPL_HPP_ */
Note: See TracBrowser for help on using the repository browser.