// Singleton.cpp // $Id$ #if !defined (ACE_SINGLETON_C) #define ACE_SINGLETON_C #define ACE_BUILD_DLL #include "ace/Singleton.h" #include "ace/Synch_T.h" #include "ace/Object_Manager.h" #if !defined (__ACE_INLINE__) #include "ace/Singleton.i" #endif /* __ACE_INLINE__ */ template void ACE_Singleton::dump (void) { ACE_TRACE ("ACE_Singleton::dump"); #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) ACE_DEBUG ((LM_DEBUG, "instance_ = %x", ACE_Singleton::instance_i ())); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ } template ACE_Singleton *& ACE_Singleton::instance_i (void) { #if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) // Pointer to the Singleton instance. This works around a bug with // G++ and it's (mis-)handling of templates and statics... static ACE_Singleton *singleton_ = 0; return singleton_; #else return ACE_Singleton::singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ } template TYPE * ACE_Singleton::instance (void) { ACE_TRACE ("ACE_Singleton::instance"); ACE_Singleton *&singleton = ACE_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 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. #endif /* ACE_MT_SAFE */ ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_exit (singleton); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) } else { // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per ACE_Singleton instantiation. static ACE_LOCK *lock = 0; if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to allocate the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); if (singleton == 0) { ACE_NEW_RETURN (singleton, (ACE_Singleton), 0); // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_exit (singleton); } } #endif /* ACE_MT_SAFE */ } return &singleton->instance_; } template void ACE_Singleton::cleanup (void *) { delete this; } #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) // Pointer to the Singleton instance. template ACE_Singleton * ACE_Singleton::singleton_ = 0; #endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ template void ACE_TSS_Singleton::dump (void) { ACE_TRACE ("ACE_TSS_Singleton::dump"); #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) ACE_DEBUG ((LM_DEBUG, "instance_ = %x", ACE_TSS_Singleton::instance_i ())); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ } template ACE_TSS_Singleton *& ACE_TSS_Singleton::instance_i (void) { #if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) // Pointer to the Singleton instance. This works around a bug with // G++ and it's (mis-)handling of templates and statics... static ACE_TSS_Singleton *singleton_ = 0; return singleton_; #else return ACE_TSS_Singleton::singleton_; #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ } template TYPE * ACE_TSS_Singleton::instance (void) { ACE_TRACE ("ACE_TSS_Singleton::instance"); ACE_TSS_Singleton *&singleton = ACE_TSS_Singleton::instance_i (); // Perform the Double-Check pattern... if (singleton == 0) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 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. #endif /* ACE_MT_SAFE */ ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), 0); #if 0 /* ACE_Object_Manager::at_thread_exit () is not implemented yet. */ // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_thread_exit (singleton); #endif /* 0 */ #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) } else { // Obtain a lock from the ACE_Object_Manager. The pointer // is static, so we only obtain one per ACE_Singleton instantiation. static ACE_LOCK *lock = 0; if (ACE_Object_Manager::get_singleton_lock (lock) != 0) // Failed to allocate the lock! return 0; ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0); if (singleton == 0) { ACE_NEW_RETURN (singleton, (ACE_TSS_Singleton), 0); #if 0 /* ACE_Object_Manager::at_thread_exit () is not implemented yet. */ // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_thread_exit (singleton); #endif /* 0 */ } } #endif /* ACE_MT_SAFE */ } return ACE_TSS_GET (&singleton->instance_, TYPE); } template void ACE_TSS_Singleton::cleanup (void *) { ACE_TRACE ("ACE_TSS_Singleton::cleanup"); delete this; } #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) // Pointer to the Singleton instance. template ACE_TSS_Singleton * ACE_TSS_Singleton::singleton_ = 0; #endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ #endif /* ACE_SINGLETON_C */