Ticket #3859: singleton.hpp

File singleton.hpp, 2.2 KB (added by achinkoff@…, 13 years ago)

Thread safe "Singleton" pattern implementation.

Line 
1#ifndef __SINGLETON_HPP__
2#define __SINGLETON_HPP__
3
4#include <boost/thread/mutex.hpp>
5#include <boost/thread/thread.hpp>
6
7#include <boost/noncopyable.hpp>
8
9namespace boost
10{
11 /**
12 Thanks to A. Alexandrescu for CTAssert concept.
13 */
14
15 template<bool> class CTAssert;
16 template<> class CTAssert<false>{ };
17
18 /**
19 See http://www.research.ibm.com/designpatterns/pubs/ph-jun96.txt
20 about Singletons and Destroyers.
21 This is destroyer for Singleton.
22 Singleton must not be array.
23 */
24
25 template<class Doomed>
26 class SingletonDestroyer : boost::noncopyable
27 {
28 /**
29 SingletonDestroyer is only used with Singleton.
30 The goal of SingletonDestroyer - to delete
31 Singleton instance at program exit.
32 */
33
34 template<class> friend class Singleton;
35
36 private:
37 Doomed* doomed_;
38 private:
39 SingletonDestroyer()
40 {
41 typedef typename boost::is_array<Doomed>::type DoomedArrayType;
42 CTAssert<DoomedArrayType::value>
43 ____DOOMED_SINGLETON_MUST_NOT_BE_ARRAY____;
44 /**
45 Suppress unused variable warning
46 */
47 ____DOOMED_SINGLETON_MUST_NOT_BE_ARRAY____;
48 }
49 ~SingletonDestroyer(){ delete doomed_; }
50 private:
51 void set_doomed(Doomed* doomed){ doomed_ = doomed; }
52 };
53
54 template<class T>
55 class Singleton : boost::noncopyable
56 {
57 private:
58 static T* instance_;
59 static SingletonDestroyer<T> destroyer_;
60 static boost::mutex mtx_instance_;
61 public:
62 static T& Instance()
63 {
64 /**
65 Perform the Double-Check pattern.
66 See http://www.research.ibm.com/designpatterns/pubs/ph-jun96.txt.
67 */
68
69 if (instance_ == NULL)
70 {
71 boost::mutex::scoped_lock locker(mtx_instance_);
72 if (instance_ == NULL)
73 {
74 instance_ = new T();
75 destroyer_.set_doomed(instance_);
76 }
77 }
78
79 return *instance_;
80 }
81 };
82
83 template<typename T> T* Singleton<T>::instance_ = NULL;
84 template<typename T> SingletonDestroyer<T> Singleton<T>::destroyer_;
85 template<typename T> boost::mutex Singleton<T>::mtx_instance_;
86
87} // !namespace boost
88
89#define SINGLETON_IS_MY_FRIEND \
90template<class> friend class Singleton; \
91template<class> friend class SingletonDestroyer;
92
93#endif // __SINGLETON_HPP__
94