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__ */
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.
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 */
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 */
51 (void) TAO_Singleton_Manager::instance ()->fini ();
56 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
58 TAO_Singleton_Manager::TAO_Singleton_Manager ()
59 : default_mask_ (nullptr),
60 thread_hook_ (nullptr),
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)
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()
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 */
97 TAO_Singleton_Manager::default_mask ()
99 return TAO_Singleton_Manager::instance ()->default_mask_
;
103 TAO_Singleton_Manager::thread_hook ()
105 return TAO_Singleton_Manager::instance ()->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
;
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
,
130 ACE_ASSERT (instance_pointer
== the_instance
);
132 instance_pointer
->dynamically_allocated_
= true;
134 return instance_pointer
;
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
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
178 this->object_manager_state_
= OBJ_MAN_INITIALIZED
;
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
200 if (this->registered_with_object_manager_
== -1)
202 if (register_with_object_manager
== 1
203 && ACE_Object_Manager::at_exit (
205 (ACE_CLEANUP_FUNC
) TAO_SINGLETON_MANAGER_CLEANUP_DESTROYER_NAME
,
207 typeid (*this).name ()) != 0)
210 this->registered_with_object_manager_
= register_with_object_manager
;
213 // Had already initialized.
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
237 this->object_manager_state_
= OBJ_MAN_SHUTTING_DOWN
;
239 // If another Object_Manager has registered for termination, do it.
242 this->next_
->fini ();
243 this->next_
= nullptr; // Protect against recursive calls.
246 // Call all registered cleanup hooks, in reverse order of
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_
)
274 TAO_Singleton_Manager::starting_up ()
278 ? the_instance
->starting_up_i ()
283 TAO_Singleton_Manager::shutting_down ()
287 ? the_instance
->shutting_down_i ()
292 TAO_Singleton_Manager::at_exit_i (void *object
,
293 ACE_CLEANUP_FUNC cleanup_hook
,
297 ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX
,
299 *the_instance
->internal_lock_
,
302 if (this->shutting_down_i ())
308 if (this->exit_info_
.find (object
))
310 // The object has already been registered.
315 return this->exit_info_
.at_exit_i (object
, cleanup_hook
, param
, name
);
318 TAO_END_VERSIONED_NAMESPACE_DECL