00001 
00002 
00003 #include "tao/TAO_Singleton_Manager.h"
00004 #include "tao/Exception.h"
00005 
00006 #include "ace/Guard_T.h"
00007 #include "ace/Recursive_Thread_Mutex.h"
00008 #include "ace/Log_Msg.h"
00009 #include "ace/Object_Manager.h"
00010 
00011 #if !defined (__ACE_INLINE__)
00012 # include "tao/TAO_Singleton_Manager.inl"
00013 #endif 
00014 
00015 #if defined (ACE_HAS_EXCEPTIONS)
00016 # if defined (ACE_MVS)
00017 #   include  <unexpect.h>
00018 # else
00019 #  if defined (ACE_HAS_STANDARD_CPP_LIBRARY)
00020 #   include  <exception>
00021 #  else
00022 #   include  <exception.h>
00023 #  endif 
00024 # endif 
00025 #endif 
00026 
00027 ACE_RCSID (tao,
00028            TAO_Singleton_Manager,
00029            "TAO_Singleton_Manager.cpp,v 1.20 2006/04/19 08:58:21 jwillemsen Exp")
00030 
00031 
00032 namespace
00033 {
00034   
00035   TAO_Singleton_Manager * the_instance = 0;
00036 }
00037 
00038 #if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
00039 # define TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME ACE_PREPROC_CONCATENATE(TAO_VERSIONED_NAMESPACE_NAME, _TAO_Singleton_Manager_cleanup_destroyer)
00040 #endif  
00041 
00042 
00043 
00044 extern "C" void
00045 TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME (void *, void *)
00046 {
00047 #if defined (TAO_HAS_VERSIONED_NAMESPACE) \
00048     && TAO_HAS_VERSIONED_NAMESPACE == 1
00049   using namespace TAO_VERSIONED_NAMESPACE_NAME;
00050 #endif  
00051 
00052   if (the_instance)
00053     {
00054       (void) TAO_Singleton_Manager::instance ()->fini ();
00055     }
00056 }
00057 
00058 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00059 
00060 TAO_Singleton_Manager::TAO_Singleton_Manager (void)
00061   
00062   : thread_hook_ (0),
00063     exit_info_ (),
00064     registered_with_object_manager_ (-1)
00065 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00066     , internal_lock_ (new TAO_SYNCH_RECURSIVE_MUTEX)
00067 # endif 
00068 #if defined (ACE_HAS_EXCEPTIONS)
00069     , old_unexpected_ (0)
00070 #endif  
00071 {
00072   
00073   if (the_instance == 0)
00074     {
00075       the_instance = this;
00076     }
00077 
00078   
00079   
00080   
00081   
00082   int register_with_object_manager = -1;
00083   (void) this->init (register_with_object_manager);
00084 }
00085 
00086 TAO_Singleton_Manager::~TAO_Singleton_Manager (void)
00087 {
00088   this->dynamically_allocated_ = 0;   
00089   (void) this->fini ();
00090 }
00091 
00092 sigset_t *
00093 TAO_Singleton_Manager::default_mask (void)
00094 {
00095   return TAO_Singleton_Manager::instance ()->default_mask_;
00096 }
00097 
00098 ACE_Thread_Hook *
00099 TAO_Singleton_Manager::thread_hook (void)
00100 {
00101   return TAO_Singleton_Manager::instance ()->thread_hook_;
00102 }
00103 
00104 ACE_Thread_Hook *
00105 TAO_Singleton_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook)
00106 {
00107   TAO_Singleton_Manager *tao_om = TAO_Singleton_Manager::instance ();
00108   ACE_Thread_Hook *old_hook = tao_om->thread_hook_;
00109   tao_om->thread_hook_ = new_thread_hook;
00110   return old_hook;
00111 }
00112 
00113 TAO_Singleton_Manager *
00114 TAO_Singleton_Manager::instance (void)
00115 {
00116   
00117   
00118   
00119 
00120   if (the_instance == 0)
00121     {
00122       TAO_Singleton_Manager *instance_pointer;
00123 
00124       ACE_NEW_RETURN (instance_pointer,
00125                       TAO_Singleton_Manager,
00126                       0);
00127       ACE_ASSERT (instance_pointer == the_instance);
00128 
00129       instance_pointer->dynamically_allocated_ = 1;
00130 
00131       return instance_pointer;
00132     }
00133   else
00134     {
00135       return the_instance;
00136     }
00137 }
00138 
00139 int
00140 TAO_Singleton_Manager::init (void)
00141 {
00142   if (this->registered_with_object_manager_ == -1)
00143     {
00144       
00145       
00146       int register_with_object_manager = 1;
00147 
00148       return this->init (register_with_object_manager);
00149     }
00150 
00151   return 1;  
00152 }
00153 
00154 int
00155 TAO_Singleton_Manager::init (int register_with_object_manager)
00156 {
00157   if (this->starting_up_i ())
00158     {
00159       
00160       
00161       this->object_manager_state_ = OBJ_MAN_INITIALIZING;
00162 
00163       if (this == the_instance)
00164         {
00165 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00166           
00167 # endif 
00168         }
00169 
00170       ACE_NEW_RETURN (this->default_mask_, sigset_t, -1);
00171       ACE_OS::sigfillset (this->default_mask_);
00172 
00173       
00174       
00175       this->object_manager_state_ = OBJ_MAN_INITIALIZED;
00176 
00177       return 0;
00178     }
00179 
00180   
00181   
00182   
00183   
00184   
00185   
00186   if (this->registered_with_object_manager_ != -1
00187       && register_with_object_manager != this->registered_with_object_manager_)
00188     {
00189       
00190       
00191       
00192       
00193 
00194       errno = EINVAL;
00195       return -1;
00196     }
00197 
00198   if (this->registered_with_object_manager_ == -1)
00199     {
00200       if (register_with_object_manager == 1
00201           && ACE_Object_Manager::at_exit (
00202                this,
00203                (ACE_CLEANUP_FUNC) TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME,
00204                0) != 0)
00205         return -1;
00206 
00207       this->registered_with_object_manager_ =
00208         register_with_object_manager;
00209     }
00210 
00211   
00212   return 1;
00213 }
00214 
00215 
00216 
00217 
00218 
00219 
00220 int
00221 TAO_Singleton_Manager::fini (void)
00222 {
00223   if (the_instance == 0  ||  this->shutting_down_i ())
00224     
00225     
00226     return this->object_manager_state_ == OBJ_MAN_SHUT_DOWN  ?  1  :  -1;
00227 
00228   
00229   
00230 
00231   
00232   
00233   
00234   this->object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
00235 
00236   
00237   if (this->next_)
00238     {
00239       this->next_->fini ();
00240       this->next_ = 0;  
00241     }
00242 
00243   
00244   
00245   this->exit_info_.call_hooks ();
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260   delete this-> default_mask_;
00261   this->default_mask_ = 0;
00262 
00263 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00264   delete this->internal_lock_;
00265   this->internal_lock_ = 0;
00266 #endif 
00267 
00268 #if defined (ACE_HAS_EXCEPTIONS)
00269   
00270   
00271   
00272 # if (!defined (_MSC_VER) \
00273       && defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) \
00274       && (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB != 0)) || defined (ghs)
00275   (void) std::set_unexpected (this->old_unexpected_);
00276 # else
00277   (void) set_unexpected (this->old_unexpected_);
00278 # endif  
00279 #endif 
00280 
00281   
00282   this->object_manager_state_ = OBJ_MAN_SHUT_DOWN;
00283 
00284   if (this == the_instance)
00285     the_instance = 0;
00286 
00287   if (this->dynamically_allocated_)
00288     {
00289       delete this;
00290     }
00291 
00292   return 0;
00293 }
00294 
00295 int
00296 TAO_Singleton_Manager::starting_up (void)
00297 {
00298   return
00299     the_instance
00300     ? the_instance->starting_up_i ()
00301     : 1;
00302 }
00303 
00304 int
00305 TAO_Singleton_Manager::shutting_down (void)
00306 {
00307   return
00308     the_instance
00309     ? the_instance->shutting_down_i ()
00310     : 1;
00311 }
00312 
00313 #if defined (ACE_HAS_EXCEPTIONS)
00314 void
00315 TAO_Singleton_Manager::_set_unexpected (TAO_unexpected_handler u)
00316 {
00317   
00318   
00319   
00320   
00321   
00322   
00323 # if (!defined (_MSC_VER) \
00324       && defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB) \
00325       && (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB != 0)) || defined (ghs)
00326   this->old_unexpected_ = std::set_unexpected (u);
00327 # else
00328   this->old_unexpected_ = set_unexpected (u);
00329 # endif  
00330 }
00331 #endif 
00332 
00333 int
00334 TAO_Singleton_Manager::at_exit_i (void *object,
00335                                   ACE_CLEANUP_FUNC cleanup_hook,
00336                                   void *param)
00337 {
00338   ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX,
00339                             ace_mon,
00340                             *the_instance->internal_lock_,
00341                             -1));
00342 
00343   if (this->shutting_down_i ())
00344     {
00345       errno = EAGAIN;
00346       return -1;
00347     }
00348 
00349   if (this->exit_info_.find (object))
00350     {
00351       
00352       errno = EEXIST;
00353       return -1;
00354     }
00355 
00356   return this->exit_info_.at_exit_i (object, cleanup_hook, param);
00357 }
00358 
00359 TAO_END_VERSIONED_NAMESPACE_DECL