Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / TAO_Singleton_Manager.cpp
blob60ca39a7d9556677c073f108d036060af9edd7ad
1 #include "tao/TAO_Singleton_Manager.h"
3 #include "ace/Guard_T.h"
4 #include "ace/Recursive_Thread_Mutex.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Object_Manager.h"
7 #include "ace/os_include/os_typeinfo.h"
9 #if !defined (__ACE_INLINE__)
10 # include "tao/TAO_Singleton_Manager.inl"
11 #endif /* ! __ACE_INLINE__ */
13 namespace
15 // Singleton instance pointer.
16 TAO_Singleton_Manager * the_instance = nullptr;
19 #if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
20 # define TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME ACE_PREPROC_CONCATENATE(TAO_VERSIONED_NAMESPACE_NAME, _TAO_Singleton_Manager_cleanup_destroyer)
21 # define TAO_SINGLETON_MANAGER_FINI_NAME ACE_PREPROC_CONCATENATE(TAO_VERSIONED_NAMESPACE_NAME, _TAO_Singleton_Manager_fini)
22 #endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
24 // Adapter for cleanup, used to register cleanup function with the
25 // ACE_Object_Manager.
26 extern "C" void
27 TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME (void *, void *)
29 #if defined (TAO_HAS_VERSIONED_NAMESPACE) \
30 && TAO_HAS_VERSIONED_NAMESPACE == 1
31 using namespace TAO_VERSIONED_NAMESPACE_NAME;
32 #endif /* TAO_HAS_VERSIONED_NAMESPACE */
34 if (the_instance)
36 (void) TAO_Singleton_Manager::instance ()->fini ();
40 #if (ACE_HAS_GCC_DESTRUCTOR_ATTRIBUTE == 1)
41 static void TAO_SINGLETON_MANAGER_FINI_NAME () ACE_GCC_DESTRUCTOR_ATTRIBUTE;
43 void TAO_SINGLETON_MANAGER_FINI_NAME ()
45 #if defined (TAO_HAS_VERSIONED_NAMESPACE) \
46 && TAO_HAS_VERSIONED_NAMESPACE == 1
47 using namespace TAO_VERSIONED_NAMESPACE_NAME;
48 #endif /* TAO_HAS_VERSIONED_NAMESPACE */
49 if (the_instance)
51 (void) TAO_Singleton_Manager::instance ()->fini ();
54 #endif
56 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
58 TAO_Singleton_Manager::TAO_Singleton_Manager ()
59 : default_mask_ (nullptr),
60 thread_hook_ (nullptr),
61 exit_info_ (),
62 registered_with_object_manager_ (-1)
63 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
64 , internal_lock_ (nullptr)
65 # endif /* ACE_MT_SAFE */
67 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
68 ACE_NEW (this->internal_lock_,
69 TAO_SYNCH_RECURSIVE_MUTEX);
70 # endif /* ACE_MT_SAFE */
71 // Be sure that no further instances are created via instance ().
72 if (the_instance == nullptr)
74 the_instance = this;
77 // @@ This is a hack. Allow the TAO_Singleton_Manager to be registered
78 // with the ACE_Object_Manager (or not) in an explicit call to
79 // TAO_Singleton_Manager::init(). However, once the explicit call is
80 // made, it will not be possible to alter the setting.
81 int register_with_object_manager = -1;
82 (void) this->init (register_with_object_manager);
85 TAO_Singleton_Manager::~TAO_Singleton_Manager ()
87 this->dynamically_allocated_ = false; // Don't delete this again in fini()
88 (void) this->fini ();
90 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
91 delete this->internal_lock_;
92 this->internal_lock_ = nullptr;
93 #endif /* ACE_MT_SAFE */
96 sigset_t *
97 TAO_Singleton_Manager::default_mask ()
99 return TAO_Singleton_Manager::instance ()->default_mask_;
102 ACE_Thread_Hook *
103 TAO_Singleton_Manager::thread_hook ()
105 return TAO_Singleton_Manager::instance ()->thread_hook_;
108 ACE_Thread_Hook *
109 TAO_Singleton_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook)
111 TAO_Singleton_Manager *tao_om = TAO_Singleton_Manager::instance ();
112 ACE_Thread_Hook *old_hook = tao_om->thread_hook_;
113 tao_om->thread_hook_ = new_thread_hook;
114 return old_hook;
117 TAO_Singleton_Manager *
118 TAO_Singleton_Manager::instance ()
120 // This function should be called during construction of static
121 // instances, or before any other threads have been created in the
122 // process. So, it's not thread safe.
123 if (the_instance == nullptr)
125 TAO_Singleton_Manager *instance_pointer = nullptr;
127 ACE_NEW_RETURN (instance_pointer,
128 TAO_Singleton_Manager,
129 nullptr);
130 ACE_ASSERT (instance_pointer == the_instance);
132 instance_pointer->dynamically_allocated_ = true;
134 return instance_pointer;
136 else
138 return the_instance;
143 TAO_Singleton_Manager::init ()
145 if (this->registered_with_object_manager_ == -1)
147 // Register the TAO_Singleton_Manager with the
148 // ACE_Object_Manager.
149 int const register_with_object_manager = 1;
151 return this->init (register_with_object_manager);
154 return 1; // Already initialized.
158 TAO_Singleton_Manager::init (int register_with_object_manager)
160 if (this->starting_up_i ())
162 // First, indicate that this TAO_Singleton_Manager instance is being
163 // initialized.
164 this->object_manager_state_ = OBJ_MAN_INITIALIZING;
166 if (this == the_instance)
168 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
169 // @@ No MT-specific pre-allocated objects.
170 # endif /* ACE_MT_SAFE */
173 ACE_NEW_RETURN (this->default_mask_, sigset_t, -1);
174 ACE_OS::sigfillset (this->default_mask_);
176 // Finally, indicate that the TAO_Singleton_Manager instance has
177 // been initialized.
178 this->object_manager_state_ = OBJ_MAN_INITIALIZED;
180 return 0;
183 // @@ This strange looking code is what provides the "register on
184 // explicit call to init()" semantics. This was needed since the
185 // TAO_Singleton_Manager constructor invokes init().
186 // Unfortunately, I couldn't get rid of that init() call without
187 // breaking things. The fact things broke needs to be
188 // investigated further.
189 if (this->registered_with_object_manager_ != -1
190 && register_with_object_manager != this->registered_with_object_manager_)
192 // An attempt was made to register the TAO_Singleton_Manager
193 // with a manager of a different type from the one it is
194 // currently registered with. This indicates a problem with the
195 // caller's logic.
196 errno = EINVAL;
197 return -1;
200 if (this->registered_with_object_manager_ == -1)
202 if (register_with_object_manager == 1
203 && ACE_Object_Manager::at_exit (
204 this,
205 (ACE_CLEANUP_FUNC) TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME,
206 nullptr,
207 typeid (*this).name ()) != 0)
208 return -1;
210 this->registered_with_object_manager_ = register_with_object_manager;
213 // Had already initialized.
214 return 1;
217 // Clean up a TAO_Singleton_Manager. There can be instances of this object
218 // other than The Instance. This can happen if a user creates one for some
219 // reason. All objects clean up their per-object information and managed
220 // objects, but only The Instance cleans up the static preallocated objects.
222 TAO_Singleton_Manager::fini ()
224 if (the_instance == nullptr || this->shutting_down_i ())
226 // Too late. Or, maybe too early. Either fini () has already
227 // been called, or init () was never called.
228 return this->object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1;
231 // No mutex here. Only the main thread should destroy the singleton
232 // TAO_Singleton_Manager instance.
234 // Indicate that the TAO_Singleton_Manager instance is being shut
235 // down. This object manager should be the last one to be shut
236 // down.
237 this->object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
239 // If another Object_Manager has registered for termination, do it.
240 if (this->next_)
242 this->next_->fini ();
243 this->next_ = nullptr; // Protect against recursive calls.
246 // Call all registered cleanup hooks, in reverse order of
247 // registration.
248 this->exit_info_.call_hooks ();
250 // Remove ourselves from the ACE object manager
251 if (this->registered_with_object_manager_ == 1)
253 ACE_Object_Manager::remove_at_exit (this);
256 delete this->default_mask_;
257 this->default_mask_ = nullptr;
259 // Indicate that this TAO_Singleton_Manager instance has been shut down.
260 this->object_manager_state_ = OBJ_MAN_SHUT_DOWN;
262 if (this == the_instance)
263 the_instance = nullptr;
265 if (this->dynamically_allocated_)
267 delete this;
270 return 0;
274 TAO_Singleton_Manager::starting_up ()
276 return
277 the_instance
278 ? the_instance->starting_up_i ()
279 : 1;
283 TAO_Singleton_Manager::shutting_down ()
285 return
286 the_instance
287 ? the_instance->shutting_down_i ()
288 : 1;
292 TAO_Singleton_Manager::at_exit_i (void *object,
293 ACE_CLEANUP_FUNC cleanup_hook,
294 void *param,
295 const char *name)
297 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX,
298 ace_mon,
299 *the_instance->internal_lock_,
300 -1));
302 if (this->shutting_down_i ())
304 errno = EAGAIN;
305 return -1;
308 if (this->exit_info_.find (object))
310 // The object has already been registered.
311 errno = EEXIST;
312 return -1;
315 return this->exit_info_.at_exit_i (object, cleanup_hook, param, name);
318 TAO_END_VERSIONED_NAMESPACE_DECL