1 #ifndef ACE_SINGLETON_CPP
2 #define ACE_SINGLETON_CPP
4 #include "ace/Singleton.h"
6 #if !defined (ACE_LACKS_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...
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);
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
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!
86 ACE_GUARD_RETURN (ACE_LOCK
, ace_mon
, *lock
, 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 ());
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);
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
);
119 ACE_LOCK
**lock
= static_cast<ACE_LOCK
**> (param
);
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 ();
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...
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
>),
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!
204 ACE_GUARD_RETURN (ACE_LOCK
, ace_mon
, *lock
, 0);
205 #endif /* ACE_MT_SAFE */
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 ();
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...
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);
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!
287 ACE_GUARD_RETURN (ACE_LOCK
, ace_mon
, *lock
, 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 *)
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...
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
>),
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!
373 ACE_GUARD_RETURN (ACE_LOCK
, ace_mon
, *lock
, 0);
374 #endif /* ACE_MT_SAFE */
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 ();
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...
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
>),
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!
471 ACE_GUARD_RETURN (ACE_LOCK
, ace_mon
, *lock
, 0);
472 #endif /* ACE_MT_SAFE */
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 ();
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
526 return ACE_TEXT("ACE");
529 ACE_END_VERSIONED_NAMESPACE_DECL
531 #endif /* ACE_SINGLETON_CPP */