[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Object_Manager.cpp
blobfbe0b5c46dc242b155bbfb275398a48030618e5f
1 // $Id: Object_Manager.cpp 81450 2008-04-25 21:24:33Z mitza $
3 #include "ace/Object_Manager.h"
4 #if !defined (ACE_LACKS_ACE_TOKEN)
5 # include "ace/Token_Manager.h"
6 #endif /* ! ACE_LACKS_ACE_TOKEN */
7 #include "ace/Thread_Manager.h"
8 #if !defined (ACE_LACKS_ACE_SVCCONF)
9 # include "ace/Service_Manager.h"
10 # include "ace/Service_Config.h"
11 #endif /* ! ACE_LACKS_ACE_SVCCONF */
12 #include "ace/Signal.h"
13 #include "ace/Log_Msg.h"
14 #include "ace/Malloc.h"
15 #include "ace/Sig_Adapter.h"
16 #include "ace/Framework_Component.h"
17 #include "ace/DLL_Manager.h"
18 #include "ace/Atomic_Op.h"
19 #include "ace/OS_NS_sys_time.h"
21 #if defined (ACE_HAS_TRACE)
22 #include "ace/Trace.h"
23 #endif /* ACE_HAS_TRACE */
25 #if !defined (__ACE_INLINE__)
26 # include "ace/Object_Manager.inl"
27 #endif /* __ACE_INLINE__ */
29 #include "ace/Guard_T.h"
30 #include "ace/Null_Mutex.h"
31 #include "ace/Mutex.h"
32 #include "ace/RW_Thread_Mutex.h"
34 ACE_RCSID(ace, Object_Manager, "$Id: Object_Manager.cpp 81450 2008-04-25 21:24:33Z mitza $")
36 #if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS)
37 # define ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS
38 #endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS */
40 #if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS)
41 # define ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS
42 #endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS */
44 #if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS)
45 # define ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS
46 #endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS */
48 #if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS)
49 # define ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS
50 #endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS */
52 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
54 // Singleton pointer.
55 ACE_Object_Manager *ACE_Object_Manager::instance_ = 0;
57 void *ACE_Object_Manager::preallocated_object[
58 ACE_Object_Manager::ACE_PREALLOCATED_OBJECTS] = { 0 };
60 void *ACE_Object_Manager::preallocated_array[
61 ACE_Object_Manager::ACE_PREALLOCATED_ARRAYS] = { 0 };
63 // Handy macros for use by ACE_Object_Manager constructor to
64 // preallocate or delete an object or array, either statically (in
65 // global data) or dynamically (on the heap).
66 #if defined (ACE_HAS_STATIC_PREALLOCATION)
67 # define ACE_PREALLOCATE_OBJECT(TYPE, ID)\
69 static ACE_Cleanup_Adapter<TYPE> obj;\
70 preallocated_object[ID] = &obj;\
72 # define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\
74 static ACE_Cleanup_Adapter<TYPE> obj[COUNT];\
75 preallocated_array[ID] = &obj;\
77 #else
78 # define ACE_PREALLOCATE_OBJECT(TYPE, ID)\
80 ACE_Cleanup_Adapter<TYPE> *obj_p;\
81 ACE_NEW_RETURN (obj_p, ACE_Cleanup_Adapter<TYPE>, -1);\
82 preallocated_object[ID] = obj_p;\
84 # define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\
86 ACE_Cleanup_Adapter<TYPE[COUNT]> *array_p;\
87 ACE_NEW_RETURN (array_p, ACE_Cleanup_Adapter<TYPE[COUNT]>, -1);\
88 preallocated_array[ID] = array_p;\
90 # define ACE_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
91 ACE_CLEANUP_DESTROYER_NAME (\
92 (ACE_Cleanup_Adapter<TYPE> *) preallocated_object[ID], 0);\
93 preallocated_object[ID] = 0;
94 # define ACE_DELETE_PREALLOCATED_ARRAY(TYPE, ID, COUNT)\
95 delete (ACE_Cleanup_Adapter<TYPE[COUNT]> *) preallocated_array[ID];\
96 preallocated_array[ID] = 0;
97 #endif /* ACE_HAS_STATIC_PREALLOCATION */
99 #if !defined (ACE_LACKS_ACE_SVCCONF)
102 * @class ACE_Object_Manager_Preallocations
104 * @brief Performs preallocations of certain statically allocated services
105 * needed by ACE.
107 class ACE_Object_Manager_Preallocations
109 public:
110 ACE_Object_Manager_Preallocations (void);
111 ~ACE_Object_Manager_Preallocations (void);
113 private:
114 ACE_Static_Svc_Descriptor ace_svc_desc_ACE_Service_Manager;
117 ACE_Object_Manager_Preallocations::ACE_Object_Manager_Preallocations (void)
119 ACE_STATIC_SVC_DEFINE (ACE_Service_Manager_initializer,
120 ACE_TEXT ("ACE_Service_Manager"),
121 ACE_SVC_OBJ_T,
122 &ACE_SVC_NAME (ACE_Service_Manager),
123 ACE_Service_Type::DELETE_THIS |
124 ACE_Service_Type::DELETE_OBJ,
127 // Initialize the static service objects using the descriptors created
128 // above.
129 ace_svc_desc_ACE_Service_Manager =
130 ace_svc_desc_ACE_Service_Manager_initializer;
132 // Add to the list of static configured services.
133 ACE_Service_Config::static_svcs ()->
134 insert (&ace_svc_desc_ACE_Service_Manager);
137 ACE_Object_Manager_Preallocations::~ACE_Object_Manager_Preallocations (void)
141 #endif /* ! ACE_LACKS_ACE_SVCCONF */
144 ACE_Object_Manager::starting_up (void)
146 return ACE_Object_Manager::instance_ ? instance_->starting_up_i () : 1;
150 ACE_Object_Manager::shutting_down (void)
152 return ACE_Object_Manager::instance_ ? instance_->shutting_down_i () : 1;
155 #if defined (ACE_DISABLE_WIN32_ERROR_WINDOWS)
156 // Instead of popping up a window for exceptions, just print something out
157 LONG _stdcall ACE_UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo)
159 DWORD dwExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode;
161 if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION)
162 ACE_ERROR ((LM_ERROR, ACE_TEXT ("\nERROR: ACCESS VIOLATION\n")));
163 else
164 ACE_ERROR ((LM_ERROR, ACE_TEXT ("\nERROR: UNHANDLED EXCEPTION\n")));
166 return EXCEPTION_EXECUTE_HANDLER;
168 #endif /* ACE_DISABLE_WIN32_ERROR_WINDOWS */
170 // Initialize an ACE_Object_Manager. There can be instances of this object
171 // other than The Instance. This can happen if a user creates one for some
172 // reason. All objects set up their per-object information and managed
173 // objects, but only The Instance sets up the static preallocated objects and
174 // the (static) ACE_Service_Config signal handler.
176 ACE_Object_Manager::init (void)
178 if (starting_up_i ())
180 // First, indicate that the ACE_Object_Manager instance is being
181 // initialized.
182 object_manager_state_ = OBJ_MAN_INITIALIZING;
184 // Only The Instance sets up with ACE_OS_Object_Manager and initializes
185 // the preallocated objects.
186 if (this == instance_)
188 // Make sure that the ACE_OS_Object_Manager has been created,
189 // and register with it for chained fini ().
190 ACE_OS_Object_Manager::instance ()->next_ = this;
192 # if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
193 ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions ();
194 ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::init_functions ();
195 # endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
197 # if !defined (ACE_LACKS_ACE_SVCCONF)
198 // Construct the ACE_Service_Config's signal handler.
199 ACE_NEW_RETURN (ace_service_config_sig_handler_,
200 ACE_Sig_Adapter (&ACE_Service_Config::handle_signal), -1);
201 ACE_Service_Config::signal_handler (ace_service_config_sig_handler_);
202 # endif /* ! ACE_LACKS_ACE_SVCCONF */
204 // Allocate the preallocated (hard-coded) object instances.
205 ACE_PREALLOCATE_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK)
206 # if defined (ACE_HAS_THREADS)
207 ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
208 ACE_STATIC_OBJECT_LOCK)
209 # endif /* ACE_HAS_THREADS */
210 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
211 ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex,
212 ACE_MT_CORBA_HANDLER_LOCK)
213 ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK)
214 ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
215 ACE_SIG_HANDLER_LOCK)
216 ACE_PREALLOCATE_OBJECT (ACE_Null_Mutex, ACE_SINGLETON_NULL_LOCK)
217 ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
218 ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
219 ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
220 #if !defined (ACE_LACKS_ACE_TOKEN) && defined (ACE_HAS_TOKENS_LIBRARY)
221 ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX,
222 ACE_TOKEN_MANAGER_CREATION_LOCK)
223 ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX,
224 ACE_TOKEN_INVARIANTS_CREATION_LOCK)
225 #endif /* ! ACE_LACKS_ACE_TOKEN && ACE_HAS_TOKENS_LIBRARY */
226 ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex,
227 ACE_PROACTOR_EVENT_LOOP_LOCK)
228 # endif /* ACE_MT_SAFE */
231 if (this == instance_)
233 // Hooks for preallocated objects and arrays provided by application.
234 ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS
235 ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS
237 # if defined (ACE_HAS_TSS_EMULATION)
238 // Initialize the main thread's TS storage.
239 if (!ts_storage_initialized_)
241 ACE_TSS_Emulation::tss_open (ts_storage_);
242 ts_storage_initialized_ = true;
244 # endif /* ACE_HAS_TSS_EMULATION */
246 #if defined (ACE_DISABLE_WIN32_ERROR_WINDOWS) && \
247 defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
248 #if defined (_DEBUG) && (defined (_MSC_VER) || defined (__INTEL_COMPILER))
249 _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
250 _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
251 _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
252 _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
253 #endif /* _DEBUG && _MSC_VER || __INTEL_COMPILER */
255 // The system does not display the critical-error-handler message box
256 SetErrorMode(SEM_FAILCRITICALERRORS);
258 // And this will catch all unhandled exceptions.
259 SetUnhandledExceptionFilter (&ACE_UnhandledExceptionFilter);
260 #endif /* ACE_DISABLE_WIN32_ERROR_WINDOWS && ACE_WIN32 && !ACE_HAS_WINCE */
263 # if !defined (ACE_LACKS_ACE_SVCCONF)
264 ACE_NEW_RETURN (preallocations_,
265 ACE_Object_Manager_Preallocations,
266 -1);
267 # endif /* ! ACE_LACKS_ACE_SVCCONF */
269 // Open the main thread's ACE_Log_Msg.
270 if (0 == ACE_LOG_MSG)
271 return -1;
274 // Finally, indicate that the ACE_Object_Manager instance has
275 // been initialized.
276 object_manager_state_ = OBJ_MAN_INITIALIZED;
278 #if defined (ACE_HAS_TRACE)
279 // Allow tracing again (useful if user does init/fini/init)
280 ACE_Trace::start_tracing ();
281 #endif /* ACE_HAS_TRACE */
283 return 0;
284 } else {
285 // Had already initialized.
286 return 1;
290 #if defined (ACE_HAS_TSS_EMULATION)
292 ACE_Object_Manager::init_tss (void)
294 return ACE_Object_Manager::instance ()->init_tss_i ();
298 ACE_Object_Manager::init_tss_i (void)
300 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
301 *instance_->internal_lock_, -1));
303 if (!ts_storage_initialized_)
305 ACE_TSS_Emulation::tss_open (ts_storage_);
306 ts_storage_initialized_ = true;
309 return 0;
312 #endif
314 ACE_Object_Manager::ACE_Object_Manager (void)
315 // With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call to
316 // ACE_OS::tss_open () in the function body.
317 : exit_info_ ()
318 #if !defined (ACE_LACKS_ACE_SVCCONF)
319 , preallocations_ (0)
320 , ace_service_config_sig_handler_ (0)
321 #endif /* ! ACE_LACKS_ACE_SVCCONF */
322 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
323 , singleton_null_lock_ (0)
324 , singleton_recursive_lock_ (0)
325 #endif /* ACE_MT_SAFE */
326 #if defined (ACE_HAS_TSS_EMULATION)
327 , ts_storage_initialized_ (false)
328 #endif
330 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
331 ACE_NEW (internal_lock_, ACE_Recursive_Thread_Mutex);
332 # endif /* ACE_MT_SAFE */
334 // If instance_ was not 0, then another ACE_Object_Manager has
335 // already been instantiated (it is likely to be one initialized by way
336 // of library/DLL loading). Let this one go through construction in
337 // case there really is a good reason for it (like, ACE is a static/archive
338 // library, and this one is the non-static instance (with
339 // ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has a good reason for
340 // creating a separate one) but the original one will be the one retrieved
341 // from calls to ACE_Object_Manager::instance().
343 // Be sure that no further instances are created via instance ().
344 if (instance_ == 0)
345 instance_ = this;
347 init ();
350 ACE_Object_Manager::~ACE_Object_Manager (void)
352 dynamically_allocated_ = false; // Don't delete this again in fini()
353 fini ();
356 ACE_Object_Manager *
357 ACE_Object_Manager::instance (void)
359 // This function should be called during construction of static
360 // instances, or before any other threads have been created in
361 // the process. So, it's not thread safe.
363 if (instance_ == 0)
365 ACE_Object_Manager *instance_pointer = 0;
367 ACE_NEW_RETURN (instance_pointer,
368 ACE_Object_Manager,
370 ACE_ASSERT (instance_pointer == instance_);
372 instance_pointer->dynamically_allocated_ = true;
374 return instance_pointer;
376 else
377 return instance_;
381 ACE_Object_Manager::at_exit_i (void *object,
382 ACE_CLEANUP_FUNC cleanup_hook,
383 void *param)
385 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
386 *instance_->internal_lock_, -1));
388 if (shutting_down_i ())
390 errno = EAGAIN;
391 return -1;
394 if (exit_info_.find (object))
396 // The object has already been registered.
397 errno = EEXIST;
398 return -1;
401 return exit_info_.at_exit_i (object, cleanup_hook, param);
404 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
407 ACE_Object_Manager::get_singleton_lock (ACE_Null_Mutex *&lock)
409 if (starting_up () || shutting_down ())
411 // The preallocated lock has not been constructed yet.
412 // Therefore, the program is single-threaded at this point. Or,
413 // the ACE_Object_Manager instance has been destroyed, so the
414 // preallocated lock is not available. Allocate a lock to use,
415 // for interface compatibility, though there should be no
416 // contention on it.
417 if (ACE_Object_Manager::instance ()->singleton_null_lock_ == 0)
419 ACE_NEW_RETURN (ACE_Object_Manager::instance ()->
420 singleton_null_lock_,
421 ACE_Cleanup_Adapter<ACE_Null_Mutex>,
422 -1);
424 // Can't register with the ACE_Object_Manager here! The
425 // lock's declaration is visible to the ACE_Object_Manager
426 // destructor, so it will clean it up as a special case.
429 if (ACE_Object_Manager::instance ()->singleton_null_lock_ != 0)
430 lock = &ACE_Object_Manager::instance ()->singleton_null_lock_->
431 object ();
433 else
434 // Use the Object_Manager's preallocated lock.
435 lock = ACE_Managed_Object<ACE_Null_Mutex>::get_preallocated_object
436 (ACE_Object_Manager::ACE_SINGLETON_NULL_LOCK);
438 return 0;
442 ACE_Object_Manager::get_singleton_lock (ACE_Thread_Mutex *&lock)
444 if (lock == 0)
446 if (starting_up () || shutting_down ())
448 // The Object_Manager and its internal lock have not been
449 // constructed yet. Therefore, the program is single-
450 // threaded at this point. Or, the ACE_Object_Manager
451 // instance has been destroyed, so the internal lock is not
452 // available. Either way, we can not use double-checked
453 // locking. So, we'll leak the lock.
454 ACE_NEW_RETURN (lock,
455 ACE_Thread_Mutex,
456 -1);
458 else
460 // Allocate a new lock, but use double-checked locking to
461 // ensure that only one thread allocates it.
462 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
463 ace_mon,
464 *ACE_Object_Manager::instance ()->
465 internal_lock_,
466 -1));
468 if (lock == 0)
470 ACE_Cleanup_Adapter<ACE_Thread_Mutex> *lock_adapter;
471 ACE_NEW_RETURN (lock_adapter,
472 ACE_Cleanup_Adapter<ACE_Thread_Mutex>,
473 -1);
474 lock = &lock_adapter->object ();
476 // Register the lock for destruction at program
477 // termination. This call will cause us to grab the
478 // ACE_Object_Manager::instance ()->internal_lock_
479 // again; that's why it is a recursive lock.
480 ACE_Object_Manager::at_exit (lock_adapter);
485 return 0;
489 ACE_Object_Manager::get_singleton_lock (ACE_Mutex *&lock)
491 if (lock == 0)
493 if (starting_up () || shutting_down ())
495 // The Object_Manager and its internal lock have not been
496 // constructed yet. Therefore, the program is single-
497 // threaded at this point. Or, the ACE_Object_Manager
498 // instance has been destroyed, so the internal lock is not
499 // available. Either way, we can not use double-checked
500 // locking. So, we'll leak the lock.
502 ACE_NEW_RETURN (lock,
503 ACE_Mutex,
504 -1);
506 else
508 // Allocate a new lock, but use double-checked locking to
509 // ensure that only one thread allocates it.
510 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
511 ace_mon,
512 *ACE_Object_Manager::instance ()->
513 internal_lock_,
514 -1));
516 if (lock == 0)
518 ACE_Cleanup_Adapter<ACE_Mutex> *lock_adapter;
519 ACE_NEW_RETURN (lock_adapter,
520 ACE_Cleanup_Adapter<ACE_Mutex>,
521 -1);
522 lock = &lock_adapter->object ();
524 // Register the lock for destruction at program
525 // termination. This call will cause us to grab the
526 // ACE_Object_Manager::instance ()->internal_lock_
527 // again; that's why it is a recursive lock.
528 ACE_Object_Manager::at_exit (lock_adapter);
533 return 0;
537 ACE_Object_Manager::get_singleton_lock (ACE_Recursive_Thread_Mutex *&lock)
539 if (starting_up () || shutting_down ())
541 // The preallocated lock has not been constructed yet.
542 // Therefore, the program is single-threaded at this point. Or,
543 // the ACE_Object_Manager instance has been destroyed, so the
544 // preallocated lock is not available. Allocate a lock to use,
545 // for interface compatibility, though there should be no
546 // contention on it.
547 if (ACE_Object_Manager::instance ()->singleton_recursive_lock_ == 0)
548 ACE_NEW_RETURN (ACE_Object_Manager::instance ()->
549 singleton_recursive_lock_,
550 ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>,
551 -1);
553 // Can't register with the ACE_Object_Manager here! The lock's
554 // declaration is visible to the ACE_Object_Manager destructor,
555 // so it will clean it up as a special case.
557 if (ACE_Object_Manager::instance ()->singleton_recursive_lock_ != 0)
558 lock = &ACE_Object_Manager::instance ()->singleton_recursive_lock_->
559 object ();
561 else
563 // Use the Object_Manager's preallocated lock.
564 lock = ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::
565 get_preallocated_object (ACE_Object_Manager::
566 ACE_SINGLETON_RECURSIVE_THREAD_LOCK);
569 return 0;
573 ACE_Object_Manager::get_singleton_lock (ACE_RW_Thread_Mutex *&lock)
575 if (lock == 0)
577 if (starting_up () || shutting_down ())
579 // The Object_Manager and its internal lock have not been
580 // constructed yet. Therefore, the program is single-
581 // threaded at this point. Or, the ACE_Object_Manager
582 // instance has been destroyed, so the internal lock is not
583 // available. Either way, we can not use double-checked
584 // locking. So, we'll leak the lock.
586 ACE_NEW_RETURN (lock,
587 ACE_RW_Thread_Mutex,
588 -1);
590 else
592 // Allocate a new lock, but use double-checked locking to
593 // ensure that only one thread allocates it.
594 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
595 ace_mon,
596 *ACE_Object_Manager::instance ()->
597 internal_lock_,
598 -1));
600 if (lock == 0)
602 ACE_Cleanup_Adapter<ACE_RW_Thread_Mutex> *lock_adapter;
603 ACE_NEW_RETURN (lock_adapter,
604 ACE_Cleanup_Adapter<ACE_RW_Thread_Mutex>,
605 -1);
606 lock = &lock_adapter->object ();
609 // Register the lock for destruction at program
610 // termination. This call will cause us to grab the
611 // ACE_Object_Manager::instance ()->internal_lock_
612 // again; that's why it is a recursive lock.
613 ACE_Object_Manager::at_exit (lock_adapter);
618 return 0;
620 #endif /* ACE_MT_SAFE */
622 // Clean up an ACE_Object_Manager. There can be instances of this object
623 // other than The Instance. This can happen if (on Win32) the ACE DLL
624 // causes one to be created, or if a user creates one for some reason.
625 // Only The Instance cleans up the static preallocated objects. All objects
626 // clean up their per-object information and managed objects.
628 ACE_Object_Manager::fini (void)
630 if (shutting_down_i ())
631 // Too late. Or, maybe too early. Either fini () has already
632 // been called, or init () was never called.
633 return object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1;
635 // No mutex here. Only the main thread should destroy the singleton
636 // ACE_Object_Manager instance.
638 // Indicate that this ACE_Object_Manager instance is being
639 // shut down.
640 object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
642 // Call all registered cleanup hooks, in reverse order of
643 // registration.
644 exit_info_.call_hooks ();
646 if (this == instance_)
648 #if !defined (ACE_LACKS_ACE_SVCCONF)
649 delete preallocations_;
650 preallocations_ = 0;
651 #endif /* ! ACE_LACKS_ACE_SVCCONF */
653 #if defined (ACE_HAS_TRACE)
654 ACE_Trace::stop_tracing ();
655 #endif /* ACE_HAS_TRACE */
657 #if !defined (ACE_LACKS_ACE_SVCCONF)
658 // Close and possibly delete all service instances in the Service
659 // Repository.
660 ACE_Service_Config::fini_svcs ();
662 // Unlink all services in the Service Repository and close/delete
663 // all ACE library services and singletons.
664 ACE_Service_Config::close ();
665 #endif /* ! ACE_LACKS_ACE_SVCCONF */
667 // This must come after closing ACE_Service_Config, since it will
668 // close down it's dlls--it manages ACE_DLL_Manager.
669 ACE_Framework_Repository::close_singleton ();
670 ACE_DLL_Manager::close_singleton ();
672 # if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
673 ACE_Thread_Manager::close_singleton ();
674 # endif /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
676 // Close the main thread's TSS, including its Log_Msg instance.
677 ACE_OS::cleanup_tss (1 /* main thread */);
680 // Note: Do not access Log Msg after this since it is gone
683 // Close the ACE_Allocator.
684 ACE_Allocator::close_singleton ();
686 #if ! defined (ACE_HAS_STATIC_PREALLOCATION)
687 // Hooks for deletion of preallocated objects and arrays provided by
688 // application.
689 ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS
690 ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS
692 // Cleanup the dynamically preallocated arrays.
693 // (none)
695 // Cleanup the dynamically preallocated objects.
696 ACE_DELETE_PREALLOCATED_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK)
697 #if defined (ACE_HAS_THREADS)
698 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
699 ACE_STATIC_OBJECT_LOCK)
700 #endif /* ACE_HAS_THREADS */
701 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
702 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex,
703 ACE_MT_CORBA_HANDLER_LOCK)
704 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK)
705 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
706 ACE_SIG_HANDLER_LOCK)
707 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Null_Mutex,
708 ACE_SINGLETON_NULL_LOCK)
709 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
710 ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
711 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
712 #if !defined (ACE_LACKS_ACE_TOKEN) && defined (ACE_HAS_TOKENS_LIBRARY)
713 ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX,
714 ACE_TOKEN_MANAGER_CREATION_LOCK)
715 ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX,
716 ACE_TOKEN_INVARIANTS_CREATION_LOCK)
717 #endif /* ! ACE_LACKS_ACE_TOKEN && ACE_HAS_TOKENS_LIBRARY */
718 ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex,
719 ACE_PROACTOR_EVENT_LOOP_LOCK)
720 # endif /* ACE_MT_SAFE */
721 #endif /* ! ACE_HAS_STATIC_PREALLOCATION */
723 #if defined (ACE_HAS_THREADS)
724 ACE_Static_Object_Lock::cleanup_lock ();
725 #endif /* ACE_HAS_THREADS */
728 #if !defined (ACE_LACKS_ACE_SVCCONF)
729 delete ace_service_config_sig_handler_;
730 ace_service_config_sig_handler_ = 0;
731 #endif /* ! ACE_LACKS_ACE_SVCCONF */
733 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
734 delete internal_lock_;
735 internal_lock_ = 0;
737 delete singleton_null_lock_;
738 singleton_null_lock_ = 0;
740 delete singleton_recursive_lock_;
741 singleton_recursive_lock_ = 0;
742 #endif /* ACE_MT_SAFE */
744 // Indicate that this ACE_Object_Manager instance has been shut down.
745 object_manager_state_ = OBJ_MAN_SHUT_DOWN;
747 // Then, ensure that the ACE_OS_Object_Manager gets shut down.
748 if (this == instance_ && ACE_OS_Object_Manager::instance_)
749 ACE_OS_Object_Manager::instance_->fini ();
751 if (dynamically_allocated_)
753 delete this;
756 if (this == instance_)
757 instance_ = 0;
759 return 0;
763 #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
765 * @class ACE_Object_Manager_Manager
767 * @brief Ensure that the ACE_Object_Manager gets initialized at program
768 * startup, and destroyed at program termination.
770 * Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this
771 * class is created. Therefore, it gets created before main ()
772 * is called. And it gets destroyed after main () returns.
774 class ACE_Export ACE_Object_Manager_Manager
776 public:
777 ACE_Object_Manager_Manager (void);
778 ~ACE_Object_Manager_Manager (void);
780 private:
781 /// Save the main thread ID, so that destruction can be suppressed.
782 ACE_thread_t saved_main_thread_id_;
785 ACE_Object_Manager_Manager::ACE_Object_Manager_Manager (void)
786 : saved_main_thread_id_ (ACE_OS::thr_self ())
788 // Ensure that the Object_Manager gets initialized before any
789 // application threads have been spawned. Because this will be called
790 // during construction of static objects, that should always be the
791 // case.
792 (void) ACE_Object_Manager::instance ();
795 ACE_Object_Manager_Manager::~ACE_Object_Manager_Manager (void)
797 if (ACE_OS::thr_equal (ACE_OS::thr_self (),
798 saved_main_thread_id_))
800 delete ACE_Object_Manager::instance_;
801 ACE_Object_Manager::instance_ = 0;
803 // else if this destructor is not called by the main thread, then do
804 // not delete the ACE_Object_Manager. That causes problems, on
805 // WIN32 at least.
808 static ACE_Object_Manager_Manager ACE_Object_Manager_Manager_instance;
809 #endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */
811 #if defined (ACE_HAS_THREADS)
813 // hack to get around errors while compiling using split-cpp
814 #if !defined (ACE_IS_SPLITTING)
815 // This is global so that it doesn't have to be declared in the header
816 // file. That would cause nasty circular include problems.
817 typedef ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> ACE_Static_Object_Lock_Type;
818 static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock = 0;
819 #endif /* ! ACE_IS_SPLITTING */
821 // ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK isn't (currently) used by ACE.
822 // But, applications may find it useful for avoiding recursive calls
823 // if they have overridden operator new. Thanks to Jody Hagins
824 // <jody@atdesk.com> for contributing it.
826 ACE_Recursive_Thread_Mutex *
827 ACE_Static_Object_Lock::instance (void)
829 if (ACE_Object_Manager::starting_up () ||
830 ACE_Object_Manager::shutting_down ())
832 // The preallocated ACE_STATIC_OBJECT_LOCK has not been
833 // constructed yet. Therefore, the program is single-threaded
834 // at this point. Or, the ACE_Object_Manager instance has been
835 // destroyed, so the preallocated lock is not available.
836 // Allocate a lock to use, for interface compatibility, though
837 // there should be no contention on it.
838 if (ACE_Static_Object_Lock_lock == 0)
840 # if defined (ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK)
841 // Allocate a buffer with malloc, and then use placement
842 // new for the object, on the malloc'd buffer.
843 void *buffer =
844 ACE_OS::malloc (sizeof (*ACE_Static_Object_Lock_lock));
845 if (buffer == 0)
847 return 0;
849 // do not use ACE_NEW macros for placement new
850 ACE_Static_Object_Lock_lock = new (buffer)
851 ACE_Static_Object_Lock_Type ();
853 # else /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
854 ACE_NEW_RETURN (ACE_Static_Object_Lock_lock,
855 ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>,
857 # endif /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
860 // Can't register with the ACE_Object_Manager here! The lock's
861 // declaration is visible to the ACE_Object_Manager destructor,
862 // so it will clean it up as a special case.
864 return &ACE_Static_Object_Lock_lock->object ();
866 else
867 // Return the preallocated ACE_STATIC_OBJECT_LOCK.
868 return
869 ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
870 (ACE_Object_Manager::ACE_STATIC_OBJECT_LOCK);
873 void
874 ACE_Static_Object_Lock::cleanup_lock (void)
876 # if defined(ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK)
877 // It was malloc'd, so we need to explicitly call the dtor
878 // and then free the memory.
879 ACE_DES_FREE (ACE_Static_Object_Lock_lock,
880 ACE_OS::free,
881 ACE_Static_Object_Lock_Type);
882 # else /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
883 delete ACE_Static_Object_Lock_lock;
884 # endif /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
885 ACE_Static_Object_Lock_lock = 0;
887 #endif /* ACE_HAS_THREADS */
889 ACE_END_VERSIONED_NAMESPACE_DECL