3 //=============================================================================
9 * @author Tim Harrison <harrison@cs.wustl.edu>
10 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
12 * @author Rich Christy
13 * @author David Levine <levine@cs.wustl.edu>
15 //=============================================================================
17 #ifndef ACE_SINGLETON_H
18 #define ACE_SINGLETON_H
19 #include /**/ "ace/pre.h"
21 #include /**/ "ace/config-all.h"
22 #include "ace/TSS_T.h"
23 #include "ace/Cleanup.h"
25 #if !defined (ACE_LACKS_PRAGMA_ONCE)
27 #endif /* ACE_LACKS_PRAGMA_ONCE */
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
32 * @class ACE_Singleton
34 * @brief A Singleton Adapter uses the Adapter pattern to turn ordinary
35 * classes into Singletons optimized with the Double-Checked
36 * Locking optimization pattern.
38 * This implementation is a slight variation on the GoF
39 * Singleton pattern. In particular, a single
40 * <ACE_Singleton<TYPE, ACE_LOCK> > instance is allocated here,
41 * not a <TYPE> instance. The reason for this is to allow
42 * registration with the ACE_Object_Manager, so that the
43 * Singleton can be cleaned up when the process exits. For this
44 * scheme to work, a (static) cleanup() function must be
45 * provided. ACE_Singleton provides one so that TYPE doesn't
47 * If you want to make sure that only the singleton instance of
48 * <T> is created, and that users cannot create their own
49 * instances of <T>, do the following to class <T>:
50 * (a) Make the constructor of <T> private (or protected)
51 * (b) Make Singleton a friend of <T>
56 * friend class ACE_Singleton<foo, ACE_Null_Mutex>;
58 * foo () { cout << "foo constructed" << endl; }
59 * ~foo () { cout << "foo destroyed" << endl; }
61 * typedef ACE_Singleton<foo, ACE_Null_Mutex> FOO;
64 * @note The best types to use for ACE_LOCK are
65 * ACE_Recursive_Thread_Mutex and ACE_Null_Mutex.
66 * ACE_Recursive_Thread_Mutex should be used in multi-threaded
67 * programs in which it is possible for more than one thread to
68 * access the <ACE_Singleton<TYPE, ACE_LOCK>> instance.
69 * ACE_Null_Mutex can be used otherwise. The reason that these
70 * types of locks are best has to do with their allocation by
71 * the ACE_Object_Manager. Single ACE_Recursive_Thread_Mutex
72 * and ACE_Null_Mutex instances are used for all ACE_Singleton
73 * instantiations. However, other types of locks are allocated
74 * per ACE_Singleton instantiation.
76 template <class TYPE
, class ACE_LOCK
>
77 class ACE_Singleton
: public ACE_Cleanup
80 /// Global access point to the Singleton.
81 static TYPE
*instance ();
83 /// Cleanup method, used by @c ace_cleanup_destroyer to destroy the
85 virtual void cleanup (void *param
= 0);
87 /// Explicitly delete the Singleton instance.
90 /// Dump the state of the object.
93 /// Declare the dynamic allocation hooks.
94 ACE_ALLOC_HOOK_DECLARE
;
97 /// Default constructor.
100 /// Contained instance.
103 /// Pointer to the Singleton (ACE_Cleanup) instance.
104 static ACE_Singleton
<TYPE
, ACE_LOCK
> *singleton_
;
106 /// Get pointer to the Singleton instance.
107 static ACE_Singleton
<TYPE
, ACE_LOCK
> *&instance_i ();
111 * @class ACE_Unmanaged_Singleton
113 * @brief Same as ACE_Singleton, except does _not_ register with
114 * ACE_Object_Manager for destruction.
116 * This version of ACE_Singleton can be used if, for example,
117 * its DLL will be unloaded before the ACE_Object_Manager
118 * destroys the instance. Unlike with ACE_Singleton, the
119 * application is responsible for explicitly destroying the
120 * instance after it is no longer needed (if it wants to avoid
121 * memory leaks, at least). The close() static member function
122 * must be used to explicitly destroy the Singleton.
123 * Usage is the same as for ACE_Singleton, but note that if you
124 * you declare a friend, the friend class must still be an
125 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton.
127 template <class TYPE
, class ACE_LOCK
>
128 class ACE_Unmanaged_Singleton
: public ACE_Singleton
<TYPE
, ACE_LOCK
>
131 /// Global access point to the Singleton.
132 static TYPE
*instance ();
134 /// Explicitly delete the Singleton instance.
135 static void close ();
137 /// Dump the state of the object.
140 /// Declare the dynamic allocation hooks.
141 ACE_ALLOC_HOOK_DECLARE
;
144 /// Default constructor.
145 ACE_Unmanaged_Singleton ();
147 /// Pointer to the Singleton (ACE_Cleanup) instance.
148 static ACE_Unmanaged_Singleton
<TYPE
, ACE_LOCK
> *singleton_
;
150 /// Get pointer to the Singleton instance.
151 static ACE_Unmanaged_Singleton
<TYPE
, ACE_LOCK
> *&instance_i ();
155 * @class ACE_TSS_Singleton
157 * @brief This class uses the Adapter pattern to turn ordinary classes
158 * into Thread-specific Singletons optimized with the
159 * Double-Checked Locking optimization pattern.
161 * This implementation is another variation on the GoF Singleton
162 * pattern. In this case, a single <ACE_TSS_Singleton<TYPE,
163 * LOCK> > instance is allocated here, not a <TYPE> instance.
164 * Each call to the <instance> static method returns a Singleton
165 * whose pointer resides in thread-specific storage. As with
166 * ACE_Singleton, we use the ACE_Object_Manager so that the
167 * Singleton can be cleaned up when the process exits. For this
168 * scheme to work, a (static) cleanup() function must be
169 * provided. ACE_Singleton provides one so that TYPE doesn't
172 template <class TYPE
, class ACE_LOCK
>
173 class ACE_TSS_Singleton
: public ACE_Cleanup
176 /// Global access point to the singleton.
177 static TYPE
*instance ();
179 /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the
181 virtual void cleanup (void *param
= 0);
183 /// Dump the state of the object.
186 /// Declare the dynamic allocation hooks.
187 ACE_ALLOC_HOOK_DECLARE
;
190 /// Default constructor.
191 ACE_TSS_Singleton ();
193 /// Contained instance.
194 ACE_TSS_TYPE (TYPE
) instance_
;
196 void operator= (const ACE_TSS_Singleton
<TYPE
,ACE_LOCK
> &) = delete;
197 ACE_TSS_Singleton (const ACE_TSS_Singleton
<TYPE
,ACE_LOCK
> &) = delete;
199 /// Pointer to the Singleton (ACE_Cleanup) instance.
200 static ACE_TSS_Singleton
<TYPE
, ACE_LOCK
> *singleton_
;
202 /// Get pointer to the TSS Singleton instance.
203 static ACE_TSS_Singleton
<TYPE
, ACE_LOCK
> *&instance_i ();
207 * @class ACE_Unmanaged_TSS_Singleton
209 * @brief Same as ACE_TSS_Singleton, except does _not_ register with
210 * ACE_Object_Manager for destruction.
212 * This version of ACE_TSS_Singleton can be used if, for example, its DLL will
213 * be unloaded before the ACE_Object_Manager destroys the instance. Unlike with
214 * ACE_Singleton, the application is responsible for explicitly destroying the
215 * instance after it is no longer needed (if it wants to avoid memory leaks,
216 * at least). The close() static member function must be used to explicitly
217 * destroy the Singleton.
219 template <class TYPE
, class ACE_LOCK
>
220 class ACE_Unmanaged_TSS_Singleton
: public ACE_TSS_Singleton
<TYPE
, ACE_LOCK
>
223 /// Global access point to the singleton.
224 static TYPE
*instance ();
226 /// Explicitly delete the singleton instance.
227 static void close ();
229 /// Dump the state of the object.
232 /// Declare the dynamic allocation hooks.
233 ACE_ALLOC_HOOK_DECLARE
;
236 /// Default constructor.
237 ACE_Unmanaged_TSS_Singleton ();
239 /// Pointer to the Singleton (ACE_Cleanup) instance.
240 static ACE_Unmanaged_TSS_Singleton
<TYPE
, ACE_LOCK
> *singleton_
;
242 /// Get pointer to the Singleton instance.
243 static ACE_Unmanaged_TSS_Singleton
<TYPE
, ACE_LOCK
> *&instance_i ();
247 * @class ACE_DLL_Singleton_T
249 * @brief Same as ACE_Singleton, except that it registers for
250 * destruction with the ACE_Framework_Repository instead of
251 * with the ACE_Object_Manager directly.
253 * This version of ACE_Singleton should be used for singletons
254 * that live in a dll loaded either directly by ACE_DLL or indirectly
255 * by the ACE Service Configuration framework. Whenever ACE_DLL is ready
256 * to actually unload the dll, ACE_DLL_Singleton based dlls associated
257 * with that dll will be destroyed first. In fact, any singleton can
258 * safely use ACE_DLL_Singleton, even those that don't live in dlls. In
259 * that case, the singleton will be destroyed at normal program shutdown.
261 * The only additional requirement is that the contained class
262 * export name() and dll_name() methods. See ACE_DLL_Singleton_Adapter_T
263 * below for a convenient example of how to satisfy this
264 * requirement for the dll_name().
266 * Usage is the same as for ACE_Singleton, but note that if you
267 * you declare a friend, the friend class must still be an
268 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton.
270 template <class TYPE
, class ACE_LOCK
>
271 class ACE_DLL_Singleton_T
274 //void cleanup (void *param = 0);
276 /// Global access point to the Singleton.
277 static TYPE
*instance ();
279 /// Explicitly delete the Singleton instance.
280 static void close ();
282 static void close_singleton ();
284 /// Dump the state of the object.
287 const ACE_TCHAR
*dll_name ();
289 const ACE_TCHAR
*name ();
291 /// Declare the dynamic allocation hooks.
292 ACE_ALLOC_HOOK_DECLARE
;
295 /// Default constructor.
296 ACE_DLL_Singleton_T ();
299 ~ACE_DLL_Singleton_T ();
301 /// Contained instance.
304 /// Pointer to the Singleton instance.
305 static ACE_DLL_Singleton_T
<TYPE
, ACE_LOCK
> *singleton_
;
307 /// Get pointer to the singleton instance.
308 static ACE_DLL_Singleton_T
<TYPE
, ACE_LOCK
> *&instance_i ();
311 template <class TYPE
>
312 class ACE_DLL_Singleton_Adapter_T
: public TYPE
315 const ACE_TCHAR
*dll_name ();
317 /// Declare the dynamic allocation hooks.
318 ACE_ALLOC_HOOK_DECLARE
;
321 ACE_END_VERSIONED_NAMESPACE_DECL
323 #if defined (__ACE_INLINE__)
324 #include "ace/Singleton.inl"
325 #endif /* __ACE_INLINE__ */
327 #include "ace/Singleton.cpp"
329 #include /**/ "ace/post.h"
330 #endif /* ACE_SINGLETON_H */