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