1 #include "ace/Object_Manager_Base.h"
2 #include "ace/OS_Memory.h"
3 #include "ace/OS_NS_Thread.h"
4 #include "ace/OS_NS_sys_socket.h"
5 #include "ace/OS_NS_signal.h"
6 #include "ace/OS_NS_stdio.h"
8 #if defined (ACE_HAS_ALLOC_HOOKS)
9 # include "ace/Malloc_Base.h"
10 #endif /* ACE_HAS_ALLOC_HOOKS */
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
14 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
15 int ACE_SEH_Default_Exception_Selector (void *)
17 // this is only windows and only used here,
18 // defined in ace/config-win32-common.h.
19 return (DWORD
) ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION
;
22 int ACE_SEH_Default_Exception_Handler (void *)
26 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
28 #if defined (ACE_HAS_ALLOC_HOOKS)
29 # define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\
32 ACE_ALLOCATOR_RETURN (obj_p, static_cast<TYPE *>(ACE_Allocator::instance()->malloc(sizeof(TYPE))), -1); \
33 preallocated_object[ID] = (void *) obj_p;\
35 # define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
36 ACE_Allocator::instance()->free (preallocated_object[ID]); \
37 preallocated_object[ID] = 0;
39 # define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\
42 ACE_NEW_RETURN (obj_p, TYPE, -1);\
43 preallocated_object[ID] = (void *) obj_p;\
45 # define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
46 delete (TYPE *) preallocated_object[ID];\
47 preallocated_object[ID] = 0;
48 #endif /* ACE_HAS_ALLOC_HOOKS */
50 ACE_Object_Manager_Base::ACE_Object_Manager_Base ()
51 : object_manager_state_ (OBJ_MAN_UNINITIALIZED
)
52 , dynamically_allocated_ (false)
57 ACE_Object_Manager_Base::~ACE_Object_Manager_Base ()
59 #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
60 // Clear the flag so that fini () doesn't delete again.
61 dynamically_allocated_
= false;
62 #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */
66 ACE_Object_Manager_Base::starting_up_i ()
68 return object_manager_state_
< OBJ_MAN_INITIALIZED
;
72 ACE_Object_Manager_Base::shutting_down_i ()
74 return object_manager_state_
> OBJ_MAN_INITIALIZED
;
77 /*****************************************************************************/
81 ACE_OS_Object_Manager_Internal_Exit_Hook ()
83 if (ACE_OS_Object_Manager::instance_
)
84 ACE_OS_Object_Manager::instance ()->fini ();
87 ACE_OS_Object_Manager
*ACE_OS_Object_Manager::instance_
= 0;
89 void *ACE_OS_Object_Manager::preallocated_object
[
90 ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS
] = { 0 };
92 ACE_OS_Object_Manager::ACE_OS_Object_Manager ()
96 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
97 , seh_except_selector_ (ACE_SEH_Default_Exception_Selector
)
98 , seh_except_handler_ (ACE_SEH_Default_Exception_Handler
)
99 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
101 // If instance_ was not 0, then another ACE_OS_Object_Manager has
102 // already been instantiated (it is likely to be one initialized by
103 // way of library/DLL loading). Let this one go through
104 // construction in case there really is a good reason for it (like,
105 // ACE is a static/archive library, and this one is the non-static
106 // instance (with ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has
107 // a good reason for creating a separate one) but the original one
108 // will be the one retrieved from calls to
109 // ACE_Object_Manager::instance().
111 // Be sure that no further instances are created via instance ().
118 ACE_OS_Object_Manager::~ACE_OS_Object_Manager ()
120 dynamically_allocated_
= false; // Don't delete this again in fini()
124 ACE_ALLOC_HOOK_DEFINE(ACE_OS_Object_Manager
)
127 ACE_OS_Object_Manager::default_mask ()
129 return ACE_OS_Object_Manager::instance ()->default_mask_
;
133 ACE_OS_Object_Manager::thread_hook ()
135 return ACE_OS_Object_Manager::instance ()->thread_hook_
;
138 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
139 ACE_SEH_EXCEPT_HANDLER
140 ACE_OS_Object_Manager::seh_except_selector ()
142 return ACE_OS_Object_Manager::instance ()->seh_except_selector_
;
145 ACE_SEH_EXCEPT_HANDLER
146 ACE_OS_Object_Manager::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n
)
148 ACE_OS_Object_Manager
*instance
=
149 ACE_OS_Object_Manager::instance ();
151 ACE_SEH_EXCEPT_HANDLER retv
= instance
->seh_except_selector_
;
152 instance
->seh_except_selector_
= n
;
156 ACE_SEH_EXCEPT_HANDLER
157 ACE_OS_Object_Manager::seh_except_handler ()
159 return ACE_OS_Object_Manager::instance ()->seh_except_handler_
;
162 ACE_SEH_EXCEPT_HANDLER
163 ACE_OS_Object_Manager::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n
)
165 ACE_OS_Object_Manager
*instance
=
166 ACE_OS_Object_Manager::instance ();
168 ACE_SEH_EXCEPT_HANDLER retv
= instance
->seh_except_handler_
;
169 instance
->seh_except_handler_
= n
;
172 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
175 ACE_OS_Object_Manager::thread_hook (ACE_Thread_Hook
*new_thread_hook
)
177 ACE_OS_Object_Manager
*os_om
= ACE_OS_Object_Manager::instance ();
178 ACE_Thread_Hook
*old_hook
= os_om
->thread_hook_
;
179 os_om
->thread_hook_
= new_thread_hook
;
183 ACE_OS_Object_Manager
*
184 ACE_OS_Object_Manager::instance ()
186 // This function should be called during construction of static
187 // instances, or before any other threads have been created in the
188 // process. So, it's not thread safe.
192 ACE_OS_Object_Manager
*instance_pointer
= 0;
194 ACE_NEW_RETURN (instance_pointer
,
195 ACE_OS_Object_Manager
,
197 // I (coryan) removed it, using asserts in the OS layer
198 // brings down the Log msg stuff
199 // ACE_ASSERT (instance_pointer == instance_);
201 instance_pointer
->dynamically_allocated_
= true;
208 ACE_OS_Object_Manager::init ()
210 if (starting_up_i ())
212 // First, indicate that this ACE_OS_Object_Manager instance is being
214 object_manager_state_
= OBJ_MAN_INITIALIZING
;
216 if (this == instance_
)
218 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
219 ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t
, ACE_OS_MONITOR_LOCK
)
220 if (ACE_OS::thread_mutex_init
221 (reinterpret_cast <ACE_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_OS_MONITOR_LOCK
])) != 0)
222 ACE_OS_Object_Manager::print_error_message (
223 __LINE__
, ACE_TEXT ("ACE_OS_MONITOR_LOCK"));
224 ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t
,
225 ACE_TSS_CLEANUP_LOCK
)
226 if (ACE_OS::recursive_mutex_init
227 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_CLEANUP_LOCK
])) != 0)
228 ACE_OS_Object_Manager::print_error_message (
229 __LINE__
, ACE_TEXT ("ACE_TSS_CLEANUP_LOCK"));
230 ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t
,
231 ACE_LOG_MSG_INSTANCE_LOCK
)
232 if (ACE_OS::thread_mutex_init
233 (reinterpret_cast <ACE_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_LOG_MSG_INSTANCE_LOCK
])) != 0)
234 ACE_OS_Object_Manager::print_error_message (
235 __LINE__
, ACE_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK"));
236 # if defined (ACE_HAS_TSS_EMULATION)
237 ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t
,
239 if (ACE_OS::recursive_mutex_init
240 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_KEY_LOCK
])) != 0)
241 ACE_OS_Object_Manager::print_error_message (
242 __LINE__
, ACE_TEXT ("ACE_TSS_KEY_LOCK"));
243 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
244 ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t
,
246 if (ACE_OS::recursive_mutex_init
247 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_BASE_LOCK
])) != 0)
248 ACE_OS_Object_Manager::print_error_message (
249 __LINE__
, ACE_TEXT ("ACE_TSS_BASE_LOCK"));
250 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
251 # endif /* ACE_HAS_TSS_EMULATION */
252 # endif /* ACE_MT_SAFE */
254 // Open Winsock (no-op on other platforms).
255 ACE_OS::socket_init (ACE_WSOCK_VERSION
);
257 // Register the exit hook, for use by ACE_OS::exit ().
258 ACE_OS::set_exit_hook (&ACE_OS_Object_Manager_Internal_Exit_Hook
);
261 #if defined (ACE_HAS_ALLOC_HOOKS)
262 ACE_ALLOCATOR_RETURN (default_mask_
, static_cast<sigset_t
*>(ACE_Allocator::instance()->malloc(sizeof(sigset_t
))), -1);
264 ACE_NEW_RETURN (default_mask_
, sigset_t
, -1);
265 #endif /* ACE_HAS_ALLOC_HOOKS */
266 ACE_OS::sigfillset (default_mask_
);
268 // Finally, indicate that the ACE_OS_Object_Manager instance has
270 object_manager_state_
= OBJ_MAN_INITIALIZED
;
272 # if defined (ACE_WIN32) && defined (ACE_HAS_WIN32_GETVERSION)
273 /* Since MS found it necessary to deprecate these. */
274 # pragma warning(push)
275 # pragma warning(disable:4996)
276 # if defined(__clang__)
277 # pragma clang diagnostic push
278 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
279 # endif /* __clang__ */
280 ACE_OS::win32_versioninfo_
.dwOSVersionInfoSize
=
281 sizeof (ACE_TEXT_OSVERSIONINFO
);
282 ACE_TEXT_GetVersionEx (&ACE_OS::win32_versioninfo_
);
283 # if defined(__clang__)
284 # pragma clang diagnostic pop
285 # endif /* __clang__ */
286 # pragma warning(pop)
287 # endif /* ACE_WIN32 */
290 // Had already initialized.
295 // Clean up an ACE_OS_Object_Manager. There can be instances of this object
296 // other than The Instance. This can happen if a user creates one for some
297 // reason. All objects clean up their per-object information and managed
298 // objects, but only The Instance cleans up the static preallocated objects.
300 ACE_OS_Object_Manager::fini ()
302 if (instance_
== 0 || shutting_down_i ())
303 // Too late. Or, maybe too early. Either fini () has already
304 // been called, or init () was never called.
305 return object_manager_state_
== OBJ_MAN_SHUT_DOWN
? 1 : -1;
307 // No mutex here. Only the main thread should destroy the singleton
308 // ACE_OS_Object_Manager instance.
310 // Indicate that the ACE_OS_Object_Manager instance is being shut
311 // down. This object manager should be the last one to be shut
313 object_manager_state_
= OBJ_MAN_SHUTTING_DOWN
;
315 // If another Object_Manager has registered for termination, do it.
319 next_
= 0; // Protect against recursive calls.
322 // Call all registered cleanup hooks, in reverse order of
324 exit_info_
.call_hooks ();
326 // Only clean up preallocated objects when the singleton Instance is being
328 if (this == instance_
)
330 // Close down Winsock (no-op on other platforms).
331 ACE_OS::socket_fini ();
333 #if ! defined (ACE_HAS_STATIC_PREALLOCATION)
334 // Cleanup the dynamically preallocated objects.
335 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
336 # if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
337 if (ACE_OS::thread_mutex_destroy
338 (reinterpret_cast <ACE_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_OS_MONITOR_LOCK
])) != 0)
339 # ifdef ACE_LACKS_PTHREAD_MUTEX_DESTROY
340 if (errno
!= ENOTSUP
)
342 ACE_OS_Object_Manager::print_error_message (
343 __LINE__
, ACE_TEXT ("ACE_OS_MONITOR_LOCK"));
344 # endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
345 ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t
,
347 # if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
348 if (ACE_OS::recursive_mutex_destroy
349 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_CLEANUP_LOCK
])) != 0)
350 # ifdef ACE_LACKS_PTHREAD_MUTEX_DESTROY
351 if (errno
!= ENOTSUP
)
353 ACE_OS_Object_Manager::print_error_message (
354 __LINE__
, ACE_TEXT ("ACE_TSS_CLEANUP_LOCK"));
355 # endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
356 ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t
,
357 ACE_TSS_CLEANUP_LOCK
)
358 # if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
359 if (ACE_OS::thread_mutex_destroy
360 (reinterpret_cast <ACE_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_LOG_MSG_INSTANCE_LOCK
])) != 0)
361 # ifdef ACE_LACKS_PTHREAD_MUTEX_DESTROY
362 if (errno
!= ENOTSUP
)
364 ACE_OS_Object_Manager::print_error_message (
365 __LINE__
, ACE_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK "));
366 # endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
367 ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t
,
368 ACE_LOG_MSG_INSTANCE_LOCK
)
369 # if defined (ACE_HAS_TSS_EMULATION)
370 # if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
371 if (ACE_OS::recursive_mutex_destroy
372 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_KEY_LOCK
])) != 0)
373 ACE_OS_Object_Manager::print_error_message (
374 __LINE__
, ACE_TEXT ("ACE_TSS_KEY_LOCK"));
375 # endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
376 ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t
,
378 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
379 # if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
380 if (ACE_OS::recursive_mutex_destroy
381 (reinterpret_cast <ACE_recursive_thread_mutex_t
*> (ACE_OS_Object_Manager::preallocated_object
[ACE_TSS_BASE_LOCK
])) != 0)
382 ACE_OS_Object_Manager::print_error_message (
383 __LINE__
, ACE_TEXT ("ACE_TSS_BASE_LOCK"));
384 # endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
385 ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t
,
387 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
388 # endif /* ACE_HAS_TSS_EMULATION */
389 # endif /* ACE_MT_SAFE */
390 #endif /* ! ACE_HAS_STATIC_PREALLOCATION */
393 #if defined (ACE_HAS_ALLOC_HOOKS)
394 ACE_Allocator::instance()->free(default_mask_
);
396 delete default_mask_
;
397 #endif /* ACE_HAS_ALLOC_HOOKS */
400 // Indicate that this ACE_OS_Object_Manager instance has been shut down.
401 object_manager_state_
= OBJ_MAN_SHUT_DOWN
;
403 if (dynamically_allocated_
)
408 if (this == instance_
)
414 int ace_exit_hook_marker
= 0;
417 ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func
, const char* name
)
419 return exit_info_
.at_exit_i (&ace_exit_hook_marker
,
420 reinterpret_cast <ACE_CLEANUP_FUNC
> (func
),
426 ACE_OS_Object_Manager::print_error_message (unsigned int line_number
,
427 const ACE_TCHAR
*message
)
429 // To avoid duplication of these const strings in OS.o.
430 #ifndef ACE_LACKS_STDERR
431 fprintf (stderr
, "ace/Object_Manager_Base.cpp, line %u: %s ",
433 ACE_TEXT_ALWAYS_CHAR (message
));
435 ACE_UNUSED_ARG (line_number
);
436 ACE_UNUSED_ARG (message
);
438 #if !defined (ACE_LACKS_PERROR)
440 #endif /* ACE_LACKS_PERROR */
444 ACE_OS_Object_Manager::starting_up ()
446 return ACE_OS_Object_Manager::instance_
447 ? instance_
->starting_up_i ()
452 ACE_OS_Object_Manager::shutting_down ()
454 return ACE_OS_Object_Manager::instance_
455 ? instance_
->shutting_down_i ()
459 /*****************************************************************************/
461 #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
463 * @class ACE_OS_Object_Manager_Manager
465 * @brief Ensure that the ACE_OS_Object_Manager gets initialized at
466 * program startup, and destroyed at program termination.
468 * Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this
469 * class is created. Therefore, it gets created before main ()
470 * is called. And it gets destroyed after main () returns.
472 class ACE_OS_Object_Manager_Manager
476 ACE_OS_Object_Manager_Manager ();
479 ~ACE_OS_Object_Manager_Manager ();
482 /// Save the main thread ID, so that destruction can be suppressed.
483 ACE_thread_t saved_main_thread_id_
;
486 ACE_OS_Object_Manager_Manager::ACE_OS_Object_Manager_Manager ()
487 : saved_main_thread_id_ (ACE_OS::thr_self ())
489 // Ensure that the Object_Manager gets initialized before any
490 // application threads have been spawned. Because this will be called
491 // during construction of static objects, that should always be the
493 (void) ACE_OS_Object_Manager::instance ();
496 ACE_OS_Object_Manager_Manager::~ACE_OS_Object_Manager_Manager ()
498 if (ACE_OS::thr_equal (ACE_OS::thr_self (),
499 saved_main_thread_id_
))
501 delete ACE_OS_Object_Manager::instance_
;
502 ACE_OS_Object_Manager::instance_
= 0;
504 // else if this destructor is not called by the main thread, then do
505 // not delete the ACE_OS_Object_Manager. That causes problems, on
509 static ACE_OS_Object_Manager_Manager ACE_OS_Object_Manager_Manager_instance
;
510 #endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */
512 ACE_END_VERSIONED_NAMESPACE_DECL