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