Scarab  v3.8.0
Project 8 C++ Utility Library
thread_singleton.hh
Go to the documentation of this file.
1 /*
2  * thread_local_singleton.hh
3  *
4  * Created on: Dec 31, 2019
5  * Author: N.S. Oblath
6  */
7 
8 #ifndef SCARAB_THREAD_SINGLETON_HH_
9 #define SCARAB_THREAD_SINGLETON_HH_
10 
11 #include "destroyer.hh"
12 #include "error.hh"
13 
14 #include <cstddef>
15 #include <mutex>
16 
17 namespace scarab
18 {
24 #define allow_thread_singleton_access( class_name ) \
25  friend class scarab::thread_singleton< class_name >; \
26  friend class scarab::destroyer< class_name >;
27 
44  template< class x_type >
46  {
47  public:
48  static x_type* get_instance();
49  static void kill_instance();
50 
51  template< class... x_args >
52  static x_type* create_instance( x_args... args );
53 
54  private:
55  static void construct_instance();
56  static void delete_instance();
57 
58  private:
59  thread_local static x_type* f_instance;
60  thread_local static destroyer< x_type > f_destroyer;
61 
62  protected:
63  thread_local static std::mutex f_mutex;
64 
65  protected:
67 
68  friend class destroyer< x_type >;
70  };
71 
72  template< class x_type >
73  thread_local x_type* thread_singleton< x_type >::f_instance = nullptr;
74 
75  template< class x_type >
77 
78  template< class x_type >
79  thread_local std::mutex thread_singleton< x_type >::f_mutex;
80 
81  template< class x_type >
83  {
84  if( f_instance == nullptr )
85  {
86  std::unique_lock< std::mutex > t_lock( f_mutex );
88  }
89  return f_instance;
90  }
91 
92  template< class x_type >
94  {
95  if( f_instance != nullptr )
96  {
97  std::unique_lock< std::mutex > t_lock( f_mutex );
99  }
100  return;
101  }
102 
103  template< class x_type >
104  template< class... x_args >
106  {
107  if( f_instance != nullptr )
108  {
109  throw error() << "Instance already exists; create_instance can only be called before the instance exists";
110  }
111  std::unique_lock< std::mutex > t_lock( f_mutex );
112  f_instance = new x_type( args... );
114  return f_instance;
115  }
116 
117  template< class x_type >
119  {
120  if( f_instance == nullptr )
121  {
122  f_instance = new x_type();
124  }
125  }
126 
127  template< class x_type >
129  {
130  if( f_instance != nullptr )
131  {
132  delete f_instance;
133  f_instance = nullptr;
134  f_destroyer.set_doomed( nullptr );
135  }
136  }
137 
138  template< class x_type >
140  {
141  }
142  template< class x_type >
144  {
145  }
146 
147 } /* namespace scarab */
148 
149 #endif /* SCARAB_THREAD_SINGLETON_HH_ */
void set_doomed(XDoomed *)
Definition: destroyer.hh:46
static x_type * create_instance(x_args... args)
static x_type * get_instance()
static thread_local std::mutex f_mutex
Base class that turns a class into a thread-local singleton.
static thread_local destroyer< x_type > f_destroyer
static thread_local x_type * f_instance