#ifndef ACE_SINGLETON_CPP #define ACE_SINGLETON_CPP #include "ace/Singleton.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #if !defined (__ACE_INLINE__) #include "ace/Singleton.inl" #endif /* __ACE_INLINE__ */ #include "ace/Object_Manager.h" #include "ace/Log_Category.h" #include "ace/Framework_Component.h" #include "ace/Guard_T.h" #include "ace/os_include/os_typeinfo.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Singleton) ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Unmanaged_Singleton) ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_TSS_Singleton) ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Unmanaged_TSS_Singleton) ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_DLL_Singleton_T) ACE_ALLOC_HOOK_DEFINE_Tc(ACE_DLL_Singleton_Adapter_T) template void ACE_Singleton::dump () { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Singleton::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), ACE_Singleton::instance_i ())); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } template ACE_Singleton *& ACE_Singleton::instance_i () { return ACE_Singleton::singleton_; } template TYPE * ACE_Singleton::instance () { ACE_TRACE ("ACE_Singleton::instance"); ACE_Singleton *&singleton = ACE_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) { // The program is still starting up, and therefore assumed // to be single threaded. There's no need to double-check. // Or, the ACE_Object_Manager instance has been destroyed, // so the preallocated lock is not available. Either way, // don't register for destruction with the // ACE_Object_Manager: we'll have to leak this instance. ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); } else { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per ACE_Singleton // instantiation. #if defined(ACE_FACE_SAFETY_BASE) static ACE_LOCK the_lock; static ACE_LOCK *lock = &the_lock; #else /* ACE_FACE_SAFETY_BASE */ static ACE_LOCK *lock = 0; #endif /* ACE_FACE_SAFETY_BASE */ if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to acquire the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); if (singleton == 0) { #endif /* ACE_MT_SAFE */ ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); // Register for destruction with ACE_Object_Manager. #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE == 0) ACE_Object_Manager::at_exit (singleton, 0, typeid (TYPE).name ()); #else ACE_Object_Manager::at_exit (singleton, &lock, typeid (TYPE).name ()); } #endif /* ACE_MT_SAFE */ } } return &singleton->instance_; } template void ACE_Singleton::cleanup (void *param) { ACE_Object_Manager::remove_at_exit (this); delete this; ACE_Singleton::instance_i () = 0; #if !defined ACE_MT_SAFE || ACE_MT_SAFE == 0 || defined ACE_FACE_SAFETY_BASE ACE_UNUSED_ARG (param); #else if (param) { ACE_LOCK **lock = static_cast (param); *lock = 0; } #endif } template void ACE_Singleton::close () { ACE_Singleton *&singleton = ACE_Singleton::instance_i (); if (singleton) { singleton->cleanup (); ACE_Singleton::instance_i () = 0; } } // Pointer to the Singleton instance. template ACE_Singleton * ACE_Singleton::singleton_ = 0; template ACE_Unmanaged_Singleton * ACE_Unmanaged_Singleton::singleton_ = 0; template void ACE_Unmanaged_Singleton::dump () { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Unmanaged_Singleton::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), ACE_Unmanaged_Singleton::instance_i ())); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } template ACE_Unmanaged_Singleton *& ACE_Unmanaged_Singleton::instance_i () { return ACE_Unmanaged_Singleton::singleton_; } template TYPE * ACE_Unmanaged_Singleton::instance () { ACE_TRACE ("ACE_Unmanaged_Singleton::instance"); ACE_Unmanaged_Singleton *&singleton = ACE_Unmanaged_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) { // The program is still starting up, and therefore assumed // to be single threaded. There's no need to double-check. // Or, the ACE_Object_Manager instance has been destroyed, // so the preallocated lock is not available. Either way, // don't register for destruction with the // ACE_Object_Manager: we'll have to leak this instance. ACE_NEW_RETURN (singleton, (ACE_Unmanaged_Singleton), 0); } else { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per // ACE_Unmanaged_Singleton instantiation. #if defined(ACE_FACE_SAFETY_BASE) static ACE_LOCK the_lock; static ACE_LOCK *lock = &the_lock; #else /* ACE_FACE_SAFETY_BASE */ static ACE_LOCK *lock = 0; #endif /* ACE_FACE_SAFETY_BASE */ if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to acquire the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ if (singleton == 0) ACE_NEW_RETURN (singleton, (ACE_Unmanaged_Singleton), 0); } } return &singleton->instance_; } template void ACE_Unmanaged_Singleton::close () { ACE_Unmanaged_Singleton *&singleton = ACE_Unmanaged_Singleton::instance_i (); if (singleton) { singleton->cleanup (); ACE_Unmanaged_Singleton::instance_i () = 0; } } template void ACE_TSS_Singleton::dump () { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_TSS_Singleton::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), ACE_TSS_Singleton::instance_i ())); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } template ACE_TSS_Singleton *& ACE_TSS_Singleton::instance_i () { return ACE_TSS_Singleton::singleton_; } template TYPE * ACE_TSS_Singleton::instance () { ACE_TRACE ("ACE_TSS_Singleton::instance"); ACE_TSS_Singleton *&singleton = ACE_TSS_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) { // The program is still starting up, and therefore assumed // to be single threaded. There's no need to double-check. // Or, the ACE_Object_Manager instance has been destroyed, // so the preallocated lock is not available. Either way, // don't register for destruction with the // ACE_Object_Manager: we'll have to leak this instance. ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), 0); } else { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per ACE_Singleton instantiation. #if defined(ACE_FACE_SAFETY_BASE) static ACE_LOCK the_lock; static ACE_LOCK *lock = &the_lock; #else /* ACE_FACE_SAFETY_BASE */ static ACE_LOCK *lock = 0; #endif /* ACE_FACE_SAFETY_BASE */ if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to acquire the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); if (singleton == 0) { #endif /* ACE_MT_SAFE */ ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), 0); // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_exit (singleton, 0, typeid (TYPE).name ()); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) } #endif /* ACE_MT_SAFE */ } } return ACE_TSS_GET (&singleton->instance_, TYPE); } template void ACE_TSS_Singleton::cleanup (void *) { delete this; ACE_TSS_Singleton::instance_i () = 0; } template void ACE_Unmanaged_TSS_Singleton::dump () { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Unmanaged_TSS_Singleton::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), ACE_Unmanaged_TSS_Singleton::instance_i ())); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } template ACE_Unmanaged_TSS_Singleton *& ACE_Unmanaged_TSS_Singleton::instance_i () { return ACE_Unmanaged_TSS_Singleton::singleton_; } template TYPE * ACE_Unmanaged_TSS_Singleton::instance () { ACE_TRACE ("ACE_Unmanaged_TSS_Singleton::instance"); ACE_Unmanaged_TSS_Singleton *&singleton = ACE_Unmanaged_TSS_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) { // The program is still starting up, and therefore assumed // to be single threaded. There's no need to double-check. // Or, the ACE_Object_Manager instance has been destroyed, // so the preallocated lock is not available. Either way, // don't register for destruction with the // ACE_Object_Manager: we'll have to leak this instance. ACE_NEW_RETURN (singleton, (ACE_Unmanaged_TSS_Singleton), 0); } else { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per // ACE_Unmanaged_Singleton instantiation. #if defined(ACE_FACE_SAFETY_BASE) static ACE_LOCK the_lock; static ACE_LOCK *lock = &the_lock; #else /* ACE_FACE_SAFETY_BASE */ static ACE_LOCK *lock = 0; #endif /* ACE_FACE_SAFETY_BASE */ if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to acquire the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ if (singleton == 0) ACE_NEW_RETURN (singleton, (ACE_Unmanaged_TSS_Singleton), 0); } } return ACE_TSS_GET (&singleton->instance_, TYPE); } template void ACE_Unmanaged_TSS_Singleton::close () { ACE_Unmanaged_TSS_Singleton *&singleton = ACE_Unmanaged_TSS_Singleton::instance_i (); if (singleton) singleton->cleanup (); } // Pointer to the Singleton instance. template ACE_TSS_Singleton * ACE_TSS_Singleton::singleton_ = 0; template ACE_Unmanaged_TSS_Singleton * ACE_Unmanaged_TSS_Singleton::singleton_ = 0; /*************************************************************************/ // Pointer to the Singleton instance. template ACE_DLL_Singleton_T * ACE_DLL_Singleton_T::singleton_ = 0; template void ACE_DLL_Singleton_T::dump () { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_DLL_Singleton_T::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("instance_ = %x"), ACE_DLL_Singleton_T::instance_i ())); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } template ACE_DLL_Singleton_T *& ACE_DLL_Singleton_T::instance_i () { ACE_TRACE ("ACE_DLL_Singleton_T::instance_i"); return ACE_DLL_Singleton_T::singleton_; } template TYPE * ACE_DLL_Singleton_T::instance () { ACE_TRACE ("ACE_DLL_Singleton_T::instance"); ACE_DLL_Singleton_T *&singleton = ACE_DLL_Singleton_T::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { if (ACE_Object_Manager::starting_up () || ACE_Object_Manager::shutting_down ()) { // The program is still starting up, and therefore assumed // to be single threaded. There's no need to double-check. // Or, the ACE_Object_Manager instance has been destroyed, // so the preallocated lock is not available. Either way, // don't register for destruction with the // ACE_Object_Manager: we'll have to leak this instance. ACE_NEW_RETURN (singleton, (ACE_DLL_Singleton_T), 0); } else { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per // ACE_Unmanaged_Singleton instantiation. #if defined(ACE_FACE_SAFETY_BASE) static ACE_LOCK the_lock; static ACE_LOCK *lock = &the_lock; #else /* ACE_FACE_SAFETY_BASE */ static ACE_LOCK *lock = 0; #endif /* ACE_FACE_SAFETY_BASE */ if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to acquire the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ if (singleton == 0) ACE_NEW_RETURN (singleton, (ACE_DLL_Singleton_T), 0); } //ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_DLL_Singleton, singleton); ACE_Framework_Repository::instance ()->register_component (new ACE_Framework_Component_T > (singleton)); } return &singleton->instance_; } template void ACE_DLL_Singleton_T::close () { ACE_TRACE ("ACE_DLL_Singleton_T::close"); ACE_DLL_Singleton_T *&singleton = ACE_DLL_Singleton_T::instance_i (); delete singleton; singleton = 0; } template void ACE_DLL_Singleton_T::close_singleton () { ACE_TRACE ("ACE_DLL_Singleton_T::close_singleton"); ACE_DLL_Singleton_T::close (); } template const ACE_TCHAR * ACE_DLL_Singleton_T::dll_name () { return this->instance ()->dll_name (); } template const ACE_TCHAR * ACE_DLL_Singleton_T::name () { return this->instance ()->name (); } /**********************************************************************/ template const ACE_TCHAR* ACE_DLL_Singleton_Adapter_T::dll_name () { // @todo make this a constant somewhere (or it there already is one // then use it. return ACE_TEXT("ACE"); } ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_SINGLETON_CPP */