Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / ace / Singleton.cpp
blob69d8ec6413674edcf35c16f89f9073a98fd30830
1 #ifndef ACE_SINGLETON_CPP
2 #define ACE_SINGLETON_CPP
4 #include "ace/Singleton.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 # pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #if !defined (__ACE_INLINE__)
11 #include "ace/Singleton.inl"
12 #endif /* __ACE_INLINE__ */
14 #include "ace/Object_Manager.h"
15 #include "ace/Log_Category.h"
16 #include "ace/Framework_Component.h"
17 #include "ace/Guard_T.h"
18 #include "ace/os_include/os_typeinfo.h"
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Singleton)
23 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Unmanaged_Singleton)
24 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_TSS_Singleton)
25 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Unmanaged_TSS_Singleton)
26 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_DLL_Singleton_T)
27 ACE_ALLOC_HOOK_DEFINE_Tc(ACE_DLL_Singleton_Adapter_T)
29 template <class TYPE, class ACE_LOCK> void
30 ACE_Singleton<TYPE, ACE_LOCK>::dump ()
32 #if defined (ACE_HAS_DUMP)
33 ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::dump");
35 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
36 ACE_Singleton<TYPE, ACE_LOCK>::instance_i ()));
37 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
38 #endif /* ACE_HAS_DUMP */
41 template <class TYPE, class ACE_LOCK> ACE_Singleton<TYPE, ACE_LOCK> *&
42 ACE_Singleton<TYPE, ACE_LOCK>::instance_i ()
44 return ACE_Singleton<TYPE, ACE_LOCK>::singleton_;
47 template <class TYPE, class ACE_LOCK> TYPE *
48 ACE_Singleton<TYPE, ACE_LOCK>::instance ()
50 ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::instance");
52 ACE_Singleton<TYPE, ACE_LOCK> *&singleton =
53 ACE_Singleton<TYPE, ACE_LOCK>::instance_i ();
55 // Perform the Double-Check pattern...
56 if (singleton == 0)
58 if (ACE_Object_Manager::starting_up () ||
59 ACE_Object_Manager::shutting_down ())
61 // The program is still starting up, and therefore assumed
62 // to be single threaded. There's no need to double-check.
63 // Or, the ACE_Object_Manager instance has been destroyed,
64 // so the preallocated lock is not available. Either way,
65 // don't register for destruction with the
66 // ACE_Object_Manager: we'll have to leak this instance.
68 ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
70 else
72 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
73 // Obtain a lock from the ACE_Object_Manager. The pointer
74 // is static, so we only obtain one per ACE_Singleton
75 // instantiation.
76 #if defined(ACE_FACE_SAFETY_BASE)
77 static ACE_LOCK the_lock;
78 static ACE_LOCK *lock = &the_lock;
79 #else /* ACE_FACE_SAFETY_BASE */
80 static ACE_LOCK *lock = 0;
81 #endif /* ACE_FACE_SAFETY_BASE */
82 if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
83 // Failed to acquire the lock!
84 return 0;
86 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
88 if (singleton == 0)
90 #endif /* ACE_MT_SAFE */
91 ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
93 // Register for destruction with ACE_Object_Manager.
94 #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE == 0)
95 ACE_Object_Manager::at_exit (singleton, 0, typeid (TYPE).name ());
96 #else
97 ACE_Object_Manager::at_exit (singleton, &lock,
98 typeid (TYPE).name ());
100 #endif /* ACE_MT_SAFE */
104 return &singleton->instance_;
107 template <class TYPE, class ACE_LOCK> void
108 ACE_Singleton<TYPE, ACE_LOCK>::cleanup (void *param)
110 ACE_Object_Manager::remove_at_exit (this);
111 delete this;
112 ACE_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
114 #if !defined ACE_MT_SAFE || ACE_MT_SAFE == 0 || defined ACE_FACE_SAFETY_BASE
115 ACE_UNUSED_ARG (param);
116 #else
117 if (param)
119 ACE_LOCK **lock = static_cast<ACE_LOCK **> (param);
120 *lock = 0;
122 #endif
125 template <class TYPE, class ACE_LOCK> void
126 ACE_Singleton<TYPE, ACE_LOCK>::close ()
128 ACE_Singleton<TYPE, ACE_LOCK> *&singleton =
129 ACE_Singleton<TYPE, ACE_LOCK>::instance_i ();
131 if (singleton)
133 singleton->cleanup ();
134 ACE_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
138 // Pointer to the Singleton instance.
139 template <class TYPE, class ACE_LOCK> ACE_Singleton<TYPE, ACE_LOCK> *
140 ACE_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
142 template <class TYPE, class ACE_LOCK> ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *
143 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
145 template <class TYPE, class ACE_LOCK> void
146 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::dump ()
148 #if defined (ACE_HAS_DUMP)
149 ACE_TRACE ("ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::dump");
151 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
152 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ()));
153 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
154 #endif /* ACE_HAS_DUMP */
157 template <class TYPE, class ACE_LOCK>
158 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&
159 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ()
161 return ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::singleton_;
164 template <class TYPE, class ACE_LOCK> TYPE *
165 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance ()
167 ACE_TRACE ("ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance");
169 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&singleton =
170 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ();
172 // Perform the Double-Check pattern...
173 if (singleton == 0)
175 if (ACE_Object_Manager::starting_up () ||
176 ACE_Object_Manager::shutting_down ())
178 // The program is still starting up, and therefore assumed
179 // to be single threaded. There's no need to double-check.
180 // Or, the ACE_Object_Manager instance has been destroyed,
181 // so the preallocated lock is not available. Either way,
182 // don't register for destruction with the
183 // ACE_Object_Manager: we'll have to leak this instance.
185 ACE_NEW_RETURN (singleton, (ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>),
188 else
190 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
191 // Obtain a lock from the ACE_Object_Manager. The pointer
192 // is static, so we only obtain one per
193 // ACE_Unmanaged_Singleton instantiation.
194 #if defined(ACE_FACE_SAFETY_BASE)
195 static ACE_LOCK the_lock;
196 static ACE_LOCK *lock = &the_lock;
197 #else /* ACE_FACE_SAFETY_BASE */
198 static ACE_LOCK *lock = 0;
199 #endif /* ACE_FACE_SAFETY_BASE */
200 if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
201 // Failed to acquire the lock!
202 return 0;
204 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
205 #endif /* ACE_MT_SAFE */
207 if (singleton == 0)
208 ACE_NEW_RETURN (singleton,
209 (ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>),
214 return &singleton->instance_;
217 template <class TYPE, class ACE_LOCK> void
218 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::close ()
220 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&singleton =
221 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i ();
223 if (singleton)
225 singleton->cleanup ();
226 ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
230 template <class TYPE, class ACE_LOCK> void
231 ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump ()
233 #if defined (ACE_HAS_DUMP)
234 ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::dump");
236 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
237 ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ()));
238 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
239 #endif /* ACE_HAS_DUMP */
242 template <class TYPE, class ACE_LOCK> ACE_TSS_Singleton<TYPE, ACE_LOCK> *&
243 ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ()
245 return ACE_TSS_Singleton<TYPE, ACE_LOCK>::singleton_;
248 template <class TYPE, class ACE_LOCK> TYPE *
249 ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance ()
251 ACE_TRACE ("ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance");
253 ACE_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
254 ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
256 // Perform the Double-Check pattern...
257 if (singleton == 0)
259 if (ACE_Object_Manager::starting_up () ||
260 ACE_Object_Manager::shutting_down ())
262 // The program is still starting up, and therefore assumed
263 // to be single threaded. There's no need to double-check.
264 // Or, the ACE_Object_Manager instance has been destroyed,
265 // so the preallocated lock is not available. Either way,
266 // don't register for destruction with the
267 // ACE_Object_Manager: we'll have to leak this instance.
269 ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton<TYPE, ACE_LOCK>), 0);
271 else
273 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
275 // Obtain a lock from the ACE_Object_Manager. The pointer
276 // is static, so we only obtain one per ACE_Singleton instantiation.
277 #if defined(ACE_FACE_SAFETY_BASE)
278 static ACE_LOCK the_lock;
279 static ACE_LOCK *lock = &the_lock;
280 #else /* ACE_FACE_SAFETY_BASE */
281 static ACE_LOCK *lock = 0;
282 #endif /* ACE_FACE_SAFETY_BASE */
283 if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
284 // Failed to acquire the lock!
285 return 0;
287 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
289 if (singleton == 0)
291 #endif /* ACE_MT_SAFE */
292 ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton<TYPE, ACE_LOCK>),
295 // Register for destruction with ACE_Object_Manager.
296 ACE_Object_Manager::at_exit (singleton, 0, typeid (TYPE).name ());
297 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
299 #endif /* ACE_MT_SAFE */
303 return ACE_TSS_GET (&singleton->instance_, TYPE);
306 template <class TYPE, class ACE_LOCK> void
307 ACE_TSS_Singleton<TYPE, ACE_LOCK>::cleanup (void *)
309 delete this;
310 ACE_TSS_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
313 template <class TYPE, class ACE_LOCK> void
314 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::dump ()
316 #if defined (ACE_HAS_DUMP)
317 ACE_TRACE ("ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::dump");
319 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
320 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ()));
321 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
322 #endif /* ACE_HAS_DUMP */
325 template <class TYPE, class ACE_LOCK>
326 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&
327 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ()
329 return ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::singleton_;
332 template <class TYPE, class ACE_LOCK> TYPE *
333 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance ()
335 ACE_TRACE ("ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance");
337 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
338 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
340 // Perform the Double-Check pattern...
341 if (singleton == 0)
343 if (ACE_Object_Manager::starting_up () ||
344 ACE_Object_Manager::shutting_down ())
346 // The program is still starting up, and therefore assumed
347 // to be single threaded. There's no need to double-check.
348 // Or, the ACE_Object_Manager instance has been destroyed,
349 // so the preallocated lock is not available. Either way,
350 // don't register for destruction with the
351 // ACE_Object_Manager: we'll have to leak this instance.
353 ACE_NEW_RETURN (singleton,
354 (ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>),
357 else
359 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
360 // Obtain a lock from the ACE_Object_Manager. The pointer
361 // is static, so we only obtain one per
362 // ACE_Unmanaged_Singleton instantiation.
363 #if defined(ACE_FACE_SAFETY_BASE)
364 static ACE_LOCK the_lock;
365 static ACE_LOCK *lock = &the_lock;
366 #else /* ACE_FACE_SAFETY_BASE */
367 static ACE_LOCK *lock = 0;
368 #endif /* ACE_FACE_SAFETY_BASE */
369 if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
370 // Failed to acquire the lock!
371 return 0;
373 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
374 #endif /* ACE_MT_SAFE */
376 if (singleton == 0)
377 ACE_NEW_RETURN (singleton,
378 (ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>),
383 return ACE_TSS_GET (&singleton->instance_, TYPE);
386 template <class TYPE, class ACE_LOCK> void
387 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::close ()
389 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&singleton =
390 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::instance_i ();
392 if (singleton)
393 singleton->cleanup ();
396 // Pointer to the Singleton instance.
397 template <class TYPE, class ACE_LOCK> ACE_TSS_Singleton <TYPE, ACE_LOCK> *
398 ACE_TSS_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
400 template <class TYPE, class ACE_LOCK>
401 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *
402 ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;
404 /*************************************************************************/
406 // Pointer to the Singleton instance.
407 template <class TYPE, class ACE_LOCK> ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *
408 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::singleton_ = 0;
410 template <class TYPE, class ACE_LOCK> void
411 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::dump ()
413 #if defined (ACE_HAS_DUMP)
414 ACE_TRACE ("ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::dump");
416 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"),
417 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance_i ()));
418 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
419 #endif /* ACE_HAS_DUMP */
422 template <class TYPE, class ACE_LOCK>
423 ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&
424 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance_i ()
426 ACE_TRACE ("ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance_i");
428 return ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::singleton_;
431 template <class TYPE, class ACE_LOCK> TYPE *
432 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance ()
434 ACE_TRACE ("ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance");
436 ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&singleton =
437 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance_i ();
439 // Perform the Double-Check pattern...
440 if (singleton == 0)
442 if (ACE_Object_Manager::starting_up () ||
443 ACE_Object_Manager::shutting_down ())
445 // The program is still starting up, and therefore assumed
446 // to be single threaded. There's no need to double-check.
447 // Or, the ACE_Object_Manager instance has been destroyed,
448 // so the preallocated lock is not available. Either way,
449 // don't register for destruction with the
450 // ACE_Object_Manager: we'll have to leak this instance.
452 ACE_NEW_RETURN (singleton, (ACE_DLL_Singleton_T<TYPE, ACE_LOCK>),
455 else
457 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
458 // Obtain a lock from the ACE_Object_Manager. The pointer
459 // is static, so we only obtain one per
460 // ACE_Unmanaged_Singleton instantiation.
461 #if defined(ACE_FACE_SAFETY_BASE)
462 static ACE_LOCK the_lock;
463 static ACE_LOCK *lock = &the_lock;
464 #else /* ACE_FACE_SAFETY_BASE */
465 static ACE_LOCK *lock = 0;
466 #endif /* ACE_FACE_SAFETY_BASE */
467 if (ACE_Object_Manager::get_singleton_lock (lock) != 0)
468 // Failed to acquire the lock!
469 return 0;
471 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);
472 #endif /* ACE_MT_SAFE */
474 if (singleton == 0)
475 ACE_NEW_RETURN (singleton,
476 (ACE_DLL_Singleton_T<TYPE, ACE_LOCK>),
479 //ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_DLL_Singleton<TYPE,ACE_LOCK>, singleton);
480 ACE_Framework_Repository::instance ()->register_component
481 (new ACE_Framework_Component_T<ACE_DLL_Singleton_T<TYPE, ACE_LOCK> > (singleton));
484 return &singleton->instance_;
487 template <class TYPE, class ACE_LOCK> void
488 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::close ()
490 ACE_TRACE ("ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::close");
492 ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&singleton =
493 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::instance_i ();
495 delete singleton;
496 singleton = 0;
499 template <class TYPE, class ACE_LOCK> void
500 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::close_singleton ()
502 ACE_TRACE ("ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::close_singleton");
503 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::close ();
506 template <class TYPE, class ACE_LOCK> const ACE_TCHAR *
507 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::dll_name ()
509 return this->instance ()->dll_name ();
512 template <class TYPE, class ACE_LOCK> const ACE_TCHAR *
513 ACE_DLL_Singleton_T<TYPE, ACE_LOCK>::name ()
515 return this->instance ()->name ();
519 /**********************************************************************/
521 template <class TYPE> const ACE_TCHAR*
522 ACE_DLL_Singleton_Adapter_T<TYPE>::dll_name ()
524 // @todo make this a constant somewhere (or it there already is one
525 // then use it.
526 return ACE_TEXT("ACE");
529 ACE_END_VERSIONED_NAMESPACE_DECL
531 #endif /* ACE_SINGLETON_CPP */