2
// Object_Manager_Base.cpp,v 1.5 2003/11/04 07:05:40 jwillemsen Exp
4
#include "ace/Object_Manager_Base.h"
6
ACE_RCSID(ace, Object_Manager_Base, "Object_Manager_Base.cpp,v 1.5 2003/11/04 07:05:40 jwillemsen Exp")
8
#if !defined (ACE_HAS_INLINED_OSCALLS)
9
# include "ace/Object_Manager_Base.inl"
10
#endif /* ACE_HAS_INLINED_OS_CALLS */
12
#include "ace/OS_Memory.h"
13
#include "ace/OS_NS_Thread.h"
14
#include "ace/OS_NS_sys_socket.h"
15
#include "ace/OS_NS_signal.h"
16
#include "ace/OS_NS_stdio.h"
18
#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
19
int ACE_SEH_Default_Exception_Selector (void *)
23
ACE_LIB_TEXT ("(%t) Win32 structured exception exiting thread\n")));
25
// this is only windows and only used here,
26
// defined in ace/config-win32-common.h.
27
return (DWORD) ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION;
30
int ACE_SEH_Default_Exception_Handler (void *)
34
#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
36
# define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\
39
ACE_NEW_RETURN (obj_p, TYPE, -1);\
40
preallocated_object[ID] = (void *) obj_p;\
42
# define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
43
delete (TYPE *) preallocated_object[ID];\
44
preallocated_object[ID] = 0;
46
ACE_Object_Manager_Base::ACE_Object_Manager_Base (void)
47
: object_manager_state_ (OBJ_MAN_UNINITIALIZED)
48
, dynamically_allocated_ (0)
53
ACE_Object_Manager_Base::~ACE_Object_Manager_Base (void)
55
#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
56
// Clear the flag so that fini () doesn't delete again.
57
dynamically_allocated_ = 0;
58
#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */
62
ACE_Object_Manager_Base::starting_up_i ()
64
return object_manager_state_ < OBJ_MAN_INITIALIZED;
68
ACE_Object_Manager_Base::shutting_down_i ()
70
return object_manager_state_ > OBJ_MAN_INITIALIZED;
73
/*****************************************************************************/
77
ACE_OS_Object_Manager_Internal_Exit_Hook (void)
79
if (ACE_OS_Object_Manager::instance_)
80
ACE_OS_Object_Manager::instance ()->fini ();
83
ACE_OS_Object_Manager *ACE_OS_Object_Manager::instance_ = 0;
85
void *ACE_OS_Object_Manager::preallocated_object[
86
ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS] = { 0 };
88
ACE_OS_Object_Manager::ACE_OS_Object_Manager (void)
89
// default_mask_ isn't initialized, because it's defined by <init>.
92
#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
93
, seh_except_selector_ (ACE_SEH_Default_Exception_Selector)
94
, seh_except_handler_ (ACE_SEH_Default_Exception_Handler)
95
#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
97
// If instance_ was not 0, then another ACE_OS_Object_Manager has
98
// already been instantiated (it is likely to be one initialized by
99
// way of library/DLL loading). Let this one go through
100
// construction in case there really is a good reason for it (like,
101
// ACE is a static/archive library, and this one is the non-static
102
// instance (with ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has
103
// a good reason for creating a separate one) but the original one
104
// will be the one retrieved from calls to
105
// ACE_Object_Manager::instance().
107
// Be sure that no further instances are created via instance ().
114
ACE_OS_Object_Manager::~ACE_OS_Object_Manager (void)
116
dynamically_allocated_ = 0; // Don't delete this again in fini()
121
ACE_OS_Object_Manager::default_mask (void)
123
return ACE_OS_Object_Manager::instance ()->default_mask_;
127
ACE_OS_Object_Manager::thread_hook (void)
129
return ACE_OS_Object_Manager::instance ()->thread_hook_;
132
#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
133
ACE_SEH_EXCEPT_HANDLER
134
ACE_OS_Object_Manager::seh_except_selector (void)
136
return ACE_OS_Object_Manager::instance ()->seh_except_selector_;
139
ACE_SEH_EXCEPT_HANDLER
140
ACE_OS_Object_Manager::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n)
142
ACE_OS_Object_Manager *instance =
143
ACE_OS_Object_Manager::instance ();
145
ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_selector_;
146
instance->seh_except_selector_ = n;
150
ACE_SEH_EXCEPT_HANDLER
151
ACE_OS_Object_Manager::seh_except_handler (void)
153
return ACE_OS_Object_Manager::instance ()->seh_except_handler_;
156
ACE_SEH_EXCEPT_HANDLER
157
ACE_OS_Object_Manager::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n)
159
ACE_OS_Object_Manager *instance =
160
ACE_OS_Object_Manager::instance ();
162
ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_handler_;
163
instance->seh_except_handler_ = n;
166
#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
169
ACE_OS_Object_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook)
171
ACE_OS_Object_Manager *os_om = ACE_OS_Object_Manager::instance ();
172
ACE_Thread_Hook *old_hook = os_om->thread_hook_;
173
os_om->thread_hook_ = new_thread_hook;
177
ACE_OS_Object_Manager *
178
ACE_OS_Object_Manager::instance (void)
180
// This function should be called during construction of static
181
// instances, or before any other threads have been created in the
182
// process. So, it's not thread safe.
186
ACE_OS_Object_Manager *instance_pointer;
188
ACE_NEW_RETURN (instance_pointer,
189
ACE_OS_Object_Manager,
191
// I (coryan) removed it, using asserts in the OS layer
192
// brings down the Log msg stuff
193
// ACE_ASSERT (instance_pointer == instance_);
195
instance_pointer->dynamically_allocated_ = 1;
203
ACE_OS_Object_Manager::init (void)
205
if (starting_up_i ())
207
// First, indicate that this ACE_OS_Object_Manager instance is being
209
object_manager_state_ = OBJ_MAN_INITIALIZING;
211
if (this == instance_)
213
# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
214
# if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
215
ACE_CE_Errno::init ();
216
# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
217
ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK)
218
if (ACE_OS::thread_mutex_init
219
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
220
(ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0)
221
ACE_OS_Object_Manager::print_error_message (
222
__LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK"));
223
ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
224
ACE_TSS_CLEANUP_LOCK)
225
if (ACE_OS::recursive_mutex_init
226
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
227
(ACE_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_LIB_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
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
234
(ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_LOG_MSG_INSTANCE_LOCK])) != 0)
235
ACE_OS_Object_Manager::print_error_message (
236
__LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK"));
237
# if defined (ACE_HAS_TSS_EMULATION)
238
ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
240
if (ACE_OS::recursive_mutex_init
241
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
242
(ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0)
243
ACE_OS_Object_Manager::print_error_message (
244
__LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK"));
245
# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
246
ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
248
if (ACE_OS::recursive_mutex_init
249
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
250
(ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0)
251
ACE_OS_Object_Manager::print_error_message (
252
__LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK"));
253
# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
254
# endif /* ACE_HAS_TSS_EMULATION */
255
# endif /* ACE_MT_SAFE */
257
// Open Winsock (no-op on other platforms).
258
ACE_OS::socket_init (ACE_WSOCK_VERSION);
260
// Register the exit hook, for use by ACE_OS::exit ().
261
ACE_OS::set_exit_hook (&ACE_OS_Object_Manager_Internal_Exit_Hook);
264
ACE_NEW_RETURN (default_mask_, sigset_t, -1);
265
ACE_OS::sigfillset (default_mask_);
267
// Finally, indicate that the ACE_OS_Object_Manager instance has
269
object_manager_state_ = OBJ_MAN_INITIALIZED;
271
# if defined (ACE_WIN32)
272
ACE_OS::win32_versioninfo_.dwOSVersionInfoSize =
273
sizeof (OSVERSIONINFO);
274
::GetVersionEx (&ACE_OS::win32_versioninfo_);
275
# endif /* ACE_WIN32 */
278
// Had already initialized.
283
// Clean up an ACE_OS_Object_Manager. There can be instances of this object
284
// other than The Instance. This can happen if a user creates one for some
285
// reason. All objects clean up their per-object information and managed
286
// objects, but only The Instance cleans up the static preallocated objects.
288
ACE_OS_Object_Manager::fini (void)
290
if (instance_ == 0 || shutting_down_i ())
291
// Too late. Or, maybe too early. Either fini () has already
292
// been called, or init () was never called.
293
return object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1;
295
// No mutex here. Only the main thread should destroy the singleton
296
// ACE_OS_Object_Manager instance.
298
// Indicate that the ACE_OS_Object_Manager instance is being shut
299
// down. This object manager should be the last one to be shut
301
object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
303
// If another Object_Manager has registered for termination, do it.
307
next_ = 0; // Protect against recursive calls.
310
// Call all registered cleanup hooks, in reverse order of
312
exit_info_.call_hooks ();
314
// Only clean up preallocated objects when the singleton Instance is being
316
if (this == instance_)
318
// Close down Winsock (no-op on other platforms).
319
ACE_OS::socket_fini ();
321
#if ! defined (ACE_HAS_STATIC_PREALLOCATION)
322
// Cleanup the dynamically preallocated objects.
323
# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
324
# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
325
if (ACE_OS::thread_mutex_destroy
326
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
327
(ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0)
328
ACE_OS_Object_Manager::print_error_message (
329
__LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK"));
330
# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
331
ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t,
333
# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
334
if (ACE_OS::recursive_mutex_destroy
335
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
336
(ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0)
337
ACE_OS_Object_Manager::print_error_message (
338
__LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK"));
339
# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
340
ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
341
ACE_TSS_CLEANUP_LOCK)
342
# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
343
if (ACE_OS::thread_mutex_destroy
344
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
345
(ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object [ACE_LOG_MSG_INSTANCE_LOCK])) != 0)
346
ACE_OS_Object_Manager::print_error_message (
347
__LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK "));
348
# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
349
ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t,
350
ACE_LOG_MSG_INSTANCE_LOCK)
351
# if defined (ACE_HAS_TSS_EMULATION)
352
# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
353
if (ACE_OS::recursive_mutex_destroy
354
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
355
(ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0)
356
ACE_OS_Object_Manager::print_error_message (
357
__LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK"));
358
# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
359
ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
361
# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
362
# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
363
if (ACE_OS::recursive_mutex_destroy
364
// This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
365
(ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0)
366
ACE_OS_Object_Manager::print_error_message (
367
__LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK"));
368
# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
369
ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
371
# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
372
# endif /* ACE_HAS_TSS_EMULATION */
373
# if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
374
ACE_CE_Errno::fini ();
375
# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
376
# endif /* ACE_MT_SAFE */
377
#endif /* ! ACE_HAS_STATIC_PREALLOCATION */
380
delete default_mask_;
383
// Indicate that this ACE_OS_Object_Manager instance has been shut down.
384
object_manager_state_ = OBJ_MAN_SHUT_DOWN;
386
if (dynamically_allocated_)
391
if (this == instance_)
397
int ace_exit_hook_marker = 0;
400
ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func)
402
return exit_info_.at_exit_i (&ace_exit_hook_marker,
403
ACE_reinterpret_cast (ACE_CLEANUP_FUNC, func),
408
ACE_OS_Object_Manager::print_error_message (u_int line_number,
409
const ACE_TCHAR *message)
411
// To avoid duplication of these const strings in OS.o.
412
#if !defined (ACE_HAS_WINCE)
413
fprintf (stderr, "ace/OS.cpp, line %u: %s ",
418
// @@ Need to use the following information.
419
ACE_UNUSED_ARG (line_number);
420
ACE_UNUSED_ARG (message);
422
ACE_TCHAR *lpMsgBuf = 0;
423
::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
424
FORMAT_MESSAGE_FROM_SYSTEM,
427
MAKELANGID (LANG_NEUTRAL,
430
(ACE_TCHAR *) &lpMsgBuf,
435
ACE_LIB_TEXT ("ACE_OS error"),
441
ACE_OS_Object_Manager::starting_up (void)
443
return ACE_OS_Object_Manager::instance_
444
? instance_->starting_up_i ()
449
ACE_OS_Object_Manager::shutting_down (void)
451
return ACE_OS_Object_Manager::instance_
452
? instance_->shutting_down_i ()
456
/*****************************************************************************/
458
#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
460
* @class ACE_OS_Object_Manager_Manager
462
* @brief Ensure that the <ACE_OS_Object_Manager> gets initialized at
463
* program startup, and destroyed at program termination.
465
* Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this
466
* class is created. Therefore, it gets created before main ()
467
* is called. And it gets destroyed after main () returns.
469
class ACE_OS_Object_Manager_Manager
473
ACE_OS_Object_Manager_Manager (void);
476
~ACE_OS_Object_Manager_Manager (void);
479
/// Save the main thread ID, so that destruction can be suppressed.
480
ACE_thread_t saved_main_thread_id_;
483
ACE_OS_Object_Manager_Manager::ACE_OS_Object_Manager_Manager (void)
484
: saved_main_thread_id_ (ACE_OS::thr_self ())
486
// Ensure that the Object_Manager gets initialized before any
487
// application threads have been spawned. Because this will be called
488
// during construction of static objects, that should always be the
490
(void) ACE_OS_Object_Manager::instance ();
493
ACE_OS_Object_Manager_Manager::~ACE_OS_Object_Manager_Manager (void)
495
if (ACE_OS::thr_equal (ACE_OS::thr_self (),
496
saved_main_thread_id_))
498
delete ACE_OS_Object_Manager::instance_;
499
ACE_OS_Object_Manager::instance_ = 0;
501
// else if this destructor is not called by the main thread, then do
502
// not delete the ACE_OS_Object_Manager. That causes problems, on
506
static ACE_OS_Object_Manager_Manager ACE_OS_Object_Manager_Manager_instance;
507
#endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */