Object_Manager.cpp

Go to the documentation of this file.
00001 // $Id: Object_Manager.cpp 81450 2008-04-25 21:24:33Z mitza $
00002 
00003 #include "ace/Object_Manager.h"
00004 #if !defined (ACE_LACKS_ACE_TOKEN)
00005 # include "ace/Token_Manager.h"
00006 #endif /* ! ACE_LACKS_ACE_TOKEN */
00007 #include "ace/Thread_Manager.h"
00008 #if !defined (ACE_LACKS_ACE_SVCCONF)
00009 #  include "ace/Service_Manager.h"
00010 #  include "ace/Service_Config.h"
00011 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00012 #include "ace/Signal.h"
00013 #include "ace/Log_Msg.h"
00014 #include "ace/Malloc.h"
00015 #include "ace/Sig_Adapter.h"
00016 #include "ace/Framework_Component.h"
00017 #include "ace/DLL_Manager.h"
00018 #include "ace/Atomic_Op.h"
00019 #include "ace/OS_NS_sys_time.h"
00020 
00021 #if defined (ACE_HAS_TRACE)
00022 #include "ace/Trace.h"
00023 #endif /* ACE_HAS_TRACE */
00024 
00025 #if !defined (__ACE_INLINE__)
00026 # include "ace/Object_Manager.inl"
00027 #endif /* __ACE_INLINE__ */
00028 
00029 #include "ace/Guard_T.h"
00030 #include "ace/Null_Mutex.h"
00031 #include "ace/Mutex.h"
00032 #include "ace/RW_Thread_Mutex.h"
00033 
00034 ACE_RCSID(ace, Object_Manager, "$Id: Object_Manager.cpp 81450 2008-04-25 21:24:33Z mitza $")
00035 
00036 #if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS)
00037 # define ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS
00038 #endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS */
00039 
00040 #if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS)
00041 # define ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS
00042 #endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS */
00043 
00044 #if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS)
00045 # define ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS
00046 #endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS */
00047 
00048 #if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS)
00049 # define ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS
00050 #endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS */
00051 
00052 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00053 
00054 // Singleton pointer.
00055 ACE_Object_Manager *ACE_Object_Manager::instance_ = 0;
00056 
00057 void *ACE_Object_Manager::preallocated_object[
00058   ACE_Object_Manager::ACE_PREALLOCATED_OBJECTS] = { 0 };
00059 
00060 void *ACE_Object_Manager::preallocated_array[
00061   ACE_Object_Manager::ACE_PREALLOCATED_ARRAYS] = { 0 };
00062 
00063 // Handy macros for use by ACE_Object_Manager constructor to
00064 // preallocate or delete an object or array, either statically (in
00065 // global data) or dynamically (on the heap).
00066 #if defined (ACE_HAS_STATIC_PREALLOCATION)
00067 # define ACE_PREALLOCATE_OBJECT(TYPE, ID)\
00068     {\
00069       static ACE_Cleanup_Adapter<TYPE> obj;\
00070       preallocated_object[ID] = &obj;\
00071     }
00072 # define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\
00073     {\
00074       static ACE_Cleanup_Adapter<TYPE> obj[COUNT];\
00075       preallocated_array[ID] = &obj;\
00076     }
00077 #else
00078 # define ACE_PREALLOCATE_OBJECT(TYPE, ID)\
00079     {\
00080       ACE_Cleanup_Adapter<TYPE> *obj_p;\
00081       ACE_NEW_RETURN (obj_p, ACE_Cleanup_Adapter<TYPE>, -1);\
00082       preallocated_object[ID] = obj_p;\
00083     }
00084 # define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\
00085     {\
00086       ACE_Cleanup_Adapter<TYPE[COUNT]> *array_p;\
00087       ACE_NEW_RETURN (array_p, ACE_Cleanup_Adapter<TYPE[COUNT]>, -1);\
00088       preallocated_array[ID] = array_p;\
00089     }
00090 # define ACE_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
00091     ACE_CLEANUP_DESTROYER_NAME (\
00092       (ACE_Cleanup_Adapter<TYPE> *) preallocated_object[ID], 0);\
00093     preallocated_object[ID] = 0;
00094 # define ACE_DELETE_PREALLOCATED_ARRAY(TYPE, ID, COUNT)\
00095     delete (ACE_Cleanup_Adapter<TYPE[COUNT]> *) preallocated_array[ID];\
00096     preallocated_array[ID] = 0;
00097 #endif /* ACE_HAS_STATIC_PREALLOCATION */
00098 
00099 #if !defined (ACE_LACKS_ACE_SVCCONF)
00100 
00101 /**
00102  * @class ACE_Object_Manager_Preallocations
00103  *
00104  * @brief Performs preallocations of certain statically allocated services
00105  * needed by ACE.
00106  */
00107 class ACE_Object_Manager_Preallocations
00108 {
00109 public:
00110   ACE_Object_Manager_Preallocations (void);
00111   ~ACE_Object_Manager_Preallocations (void);
00112 
00113 private:
00114   ACE_Static_Svc_Descriptor ace_svc_desc_ACE_Service_Manager;
00115 };
00116 
00117 ACE_Object_Manager_Preallocations::ACE_Object_Manager_Preallocations (void)
00118 {
00119   ACE_STATIC_SVC_DEFINE (ACE_Service_Manager_initializer,
00120                          ACE_TEXT ("ACE_Service_Manager"),
00121                          ACE_SVC_OBJ_T,
00122                          &ACE_SVC_NAME (ACE_Service_Manager),
00123                          ACE_Service_Type::DELETE_THIS |
00124                            ACE_Service_Type::DELETE_OBJ,
00125                          0)
00126 
00127   // Initialize the static service objects using the descriptors created
00128   // above.
00129   ace_svc_desc_ACE_Service_Manager =
00130     ace_svc_desc_ACE_Service_Manager_initializer;
00131 
00132   // Add to the list of static configured services.
00133   ACE_Service_Config::static_svcs ()->
00134     insert (&ace_svc_desc_ACE_Service_Manager);
00135 }
00136 
00137 ACE_Object_Manager_Preallocations::~ACE_Object_Manager_Preallocations (void)
00138 {
00139 }
00140 
00141 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00142 
00143 int
00144 ACE_Object_Manager::starting_up (void)
00145 {
00146   return ACE_Object_Manager::instance_  ?  instance_->starting_up_i ()  :  1;
00147 }
00148 
00149 int
00150 ACE_Object_Manager::shutting_down (void)
00151 {
00152   return ACE_Object_Manager::instance_  ?  instance_->shutting_down_i ()  :  1;
00153 }
00154 
00155 #if defined (ACE_DISABLE_WIN32_ERROR_WINDOWS)
00156 // Instead of popping up a window for exceptions, just print something out
00157 LONG _stdcall ACE_UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo)
00158 {
00159   DWORD dwExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode;
00160 
00161   if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION)
00162     ACE_ERROR ((LM_ERROR, ACE_TEXT ("\nERROR: ACCESS VIOLATION\n")));
00163   else
00164     ACE_ERROR ((LM_ERROR, ACE_TEXT ("\nERROR: UNHANDLED EXCEPTION\n")));
00165 
00166   return EXCEPTION_EXECUTE_HANDLER;
00167 }
00168 #endif /* ACE_DISABLE_WIN32_ERROR_WINDOWS */
00169 
00170 // Initialize an ACE_Object_Manager.  There can be instances of this object
00171 // other than The Instance.  This can happen if a user creates one for some
00172 // reason.  All objects set up their per-object information and managed
00173 // objects, but only The Instance sets up the static preallocated objects and
00174 // the (static) ACE_Service_Config signal handler.
00175 int
00176 ACE_Object_Manager::init (void)
00177 {
00178   if (starting_up_i ())
00179     {
00180       // First, indicate that the ACE_Object_Manager instance is being
00181       // initialized.
00182       object_manager_state_ = OBJ_MAN_INITIALIZING;
00183 
00184       // Only The Instance sets up with ACE_OS_Object_Manager and initializes
00185       // the preallocated objects.
00186       if (this == instance_)
00187         {
00188           // Make sure that the ACE_OS_Object_Manager has been created,
00189           // and register with it for chained fini ().
00190           ACE_OS_Object_Manager::instance ()->next_ = this;
00191 
00192 #     if defined (ACE_HAS_BUILTIN_ATOMIC_OP)
00193           ACE_Atomic_Op<ACE_Thread_Mutex, long>::init_functions ();
00194           ACE_Atomic_Op<ACE_Thread_Mutex, unsigned long>::init_functions ();
00195 #     endif /* ACE_HAS_BUILTIN_ATOMIC_OP */
00196 
00197 #     if !defined (ACE_LACKS_ACE_SVCCONF)
00198           // Construct the ACE_Service_Config's signal handler.
00199           ACE_NEW_RETURN (ace_service_config_sig_handler_,
00200                      ACE_Sig_Adapter (&ACE_Service_Config::handle_signal), -1);
00201           ACE_Service_Config::signal_handler (ace_service_config_sig_handler_);
00202 #     endif /* ! ACE_LACKS_ACE_SVCCONF */
00203 
00204           // Allocate the preallocated (hard-coded) object instances.
00205           ACE_PREALLOCATE_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK)
00206 #     if defined (ACE_HAS_THREADS)
00207           ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
00208                                   ACE_STATIC_OBJECT_LOCK)
00209 #     endif /* ACE_HAS_THREADS */
00210 #     if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00211           ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex,
00212                                   ACE_MT_CORBA_HANDLER_LOCK)
00213           ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK)
00214           ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
00215                                   ACE_SIG_HANDLER_LOCK)
00216           ACE_PREALLOCATE_OBJECT (ACE_Null_Mutex, ACE_SINGLETON_NULL_LOCK)
00217           ACE_PREALLOCATE_OBJECT (ACE_Recursive_Thread_Mutex,
00218                                   ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
00219           ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
00220 #if !defined (ACE_LACKS_ACE_TOKEN) && defined (ACE_HAS_TOKENS_LIBRARY)
00221           ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX,
00222                                   ACE_TOKEN_MANAGER_CREATION_LOCK)
00223           ACE_PREALLOCATE_OBJECT (ACE_TOKEN_CONST::MUTEX,
00224                                   ACE_TOKEN_INVARIANTS_CREATION_LOCK)
00225 #endif /* ! ACE_LACKS_ACE_TOKEN && ACE_HAS_TOKENS_LIBRARY */
00226           ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex,
00227                                   ACE_PROACTOR_EVENT_LOOP_LOCK)
00228 #     endif /* ACE_MT_SAFE */
00229         }
00230 
00231       if (this == instance_)
00232         {
00233           // Hooks for preallocated objects and arrays provided by application.
00234           ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS
00235           ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS
00236 
00237 #     if defined (ACE_HAS_TSS_EMULATION)
00238           // Initialize the main thread's TS storage.
00239           if (!ts_storage_initialized_)
00240             {
00241               ACE_TSS_Emulation::tss_open (ts_storage_);
00242               ts_storage_initialized_ = true;
00243             }
00244 #     endif /* ACE_HAS_TSS_EMULATION */
00245 
00246 #if defined (ACE_DISABLE_WIN32_ERROR_WINDOWS) && \
00247     defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00248 #if defined (_DEBUG) && (defined (_MSC_VER) || defined (__INTEL_COMPILER))
00249           _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
00250           _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
00251           _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
00252           _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
00253 #endif /* _DEBUG && _MSC_VER || __INTEL_COMPILER */
00254 
00255           // The system does not display the critical-error-handler message box
00256           SetErrorMode(SEM_FAILCRITICALERRORS);
00257 
00258           // And this will catch all unhandled exceptions.
00259           SetUnhandledExceptionFilter (&ACE_UnhandledExceptionFilter);
00260 #endif /* ACE_DISABLE_WIN32_ERROR_WINDOWS && ACE_WIN32 && !ACE_HAS_WINCE */
00261 
00262 
00263 #     if !defined (ACE_LACKS_ACE_SVCCONF)
00264           ACE_NEW_RETURN (preallocations_,
00265                           ACE_Object_Manager_Preallocations,
00266                           -1);
00267 #     endif /* ! ACE_LACKS_ACE_SVCCONF */
00268 
00269           // Open the main thread's ACE_Log_Msg.
00270           if (0 == ACE_LOG_MSG)
00271             return -1;
00272         }
00273 
00274       // Finally, indicate that the ACE_Object_Manager instance has
00275       // been initialized.
00276       object_manager_state_ = OBJ_MAN_INITIALIZED;
00277 
00278 #if defined (ACE_HAS_TRACE)
00279       // Allow tracing again (useful if user does init/fini/init)
00280       ACE_Trace::start_tracing ();
00281 #endif /* ACE_HAS_TRACE */
00282 
00283       return 0;
00284     } else {
00285       // Had already initialized.
00286       return 1;
00287     }
00288 }
00289 
00290 #if defined (ACE_HAS_TSS_EMULATION)
00291 int
00292 ACE_Object_Manager::init_tss (void)
00293 {
00294   return ACE_Object_Manager::instance ()->init_tss_i ();
00295 }
00296 
00297 int
00298 ACE_Object_Manager::init_tss_i (void)
00299 {
00300   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00301     *instance_->internal_lock_, -1));
00302 
00303   if (!ts_storage_initialized_)
00304     {
00305       ACE_TSS_Emulation::tss_open (ts_storage_);
00306       ts_storage_initialized_ = true;
00307     }
00308 
00309   return 0;
00310 }
00311 
00312 #endif
00313 
00314 ACE_Object_Manager::ACE_Object_Manager (void)
00315   // With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call to
00316   // ACE_OS::tss_open () in the function body.
00317   : exit_info_ ()
00318 #if !defined (ACE_LACKS_ACE_SVCCONF)
00319   , preallocations_ (0)
00320   , ace_service_config_sig_handler_ (0)
00321 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00322 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00323   , singleton_null_lock_ (0)
00324   , singleton_recursive_lock_ (0)
00325 #endif /* ACE_MT_SAFE */
00326 #if defined (ACE_HAS_TSS_EMULATION)
00327   , ts_storage_initialized_ (false)
00328 #endif
00329 {
00330 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00331   ACE_NEW (internal_lock_, ACE_Recursive_Thread_Mutex);
00332 # endif /* ACE_MT_SAFE */
00333 
00334   // If instance_ was not 0, then another ACE_Object_Manager has
00335   // already been instantiated (it is likely to be one initialized by way
00336   // of library/DLL loading).  Let this one go through construction in
00337   // case there really is a good reason for it (like, ACE is a static/archive
00338   // library, and this one is the non-static instance (with
00339   // ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has a good reason for
00340   // creating a separate one) but the original one will be the one retrieved
00341   // from calls to ACE_Object_Manager::instance().
00342 
00343   // Be sure that no further instances are created via instance ().
00344   if (instance_ == 0)
00345     instance_ = this;
00346 
00347   init ();
00348 }
00349 
00350 ACE_Object_Manager::~ACE_Object_Manager (void)
00351 {
00352   dynamically_allocated_ = false;   // Don't delete this again in fini()
00353   fini ();
00354 }
00355 
00356 ACE_Object_Manager *
00357 ACE_Object_Manager::instance (void)
00358 {
00359   // This function should be called during construction of static
00360   // instances, or before any other threads have been created in
00361   // the process.  So, it's not thread safe.
00362 
00363   if (instance_ == 0)
00364     {
00365       ACE_Object_Manager *instance_pointer = 0;
00366 
00367       ACE_NEW_RETURN (instance_pointer,
00368                       ACE_Object_Manager,
00369                       0);
00370       ACE_ASSERT (instance_pointer == instance_);
00371 
00372       instance_pointer->dynamically_allocated_ = true;
00373 
00374       return instance_pointer;
00375     }
00376   else
00377     return instance_;
00378 }
00379 
00380 int
00381 ACE_Object_Manager::at_exit_i (void *object,
00382                                ACE_CLEANUP_FUNC cleanup_hook,
00383                                void *param)
00384 {
00385   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00386     *instance_->internal_lock_, -1));
00387 
00388   if (shutting_down_i ())
00389     {
00390       errno = EAGAIN;
00391       return -1;
00392     }
00393 
00394   if (exit_info_.find (object))
00395     {
00396       // The object has already been registered.
00397       errno = EEXIST;
00398       return -1;
00399     }
00400 
00401   return exit_info_.at_exit_i (object, cleanup_hook, param);
00402 }
00403 
00404 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00405 
00406 int
00407 ACE_Object_Manager::get_singleton_lock (ACE_Null_Mutex *&lock)
00408 {
00409   if (starting_up ()  ||  shutting_down ())
00410     {
00411       // The preallocated lock has not been constructed yet.
00412       // Therefore, the program is single-threaded at this point.  Or,
00413       // the ACE_Object_Manager instance has been destroyed, so the
00414       // preallocated lock is not available.  Allocate a lock to use,
00415       // for interface compatibility, though there should be no
00416       // contention on it.
00417       if (ACE_Object_Manager::instance ()->singleton_null_lock_ == 0)
00418         {
00419           ACE_NEW_RETURN (ACE_Object_Manager::instance ()->
00420                             singleton_null_lock_,
00421                           ACE_Cleanup_Adapter<ACE_Null_Mutex>,
00422                           -1);
00423 
00424           // Can't register with the ACE_Object_Manager here!  The
00425           // lock's declaration is visible to the ACE_Object_Manager
00426           // destructor, so it will clean it up as a special case.
00427         }
00428 
00429       if (ACE_Object_Manager::instance ()->singleton_null_lock_ != 0)
00430         lock = &ACE_Object_Manager::instance ()->singleton_null_lock_->
00431           object ();
00432     }
00433   else
00434     // Use the Object_Manager's preallocated lock.
00435     lock = ACE_Managed_Object<ACE_Null_Mutex>::get_preallocated_object
00436       (ACE_Object_Manager::ACE_SINGLETON_NULL_LOCK);
00437 
00438   return 0;
00439 }
00440 
00441 int
00442 ACE_Object_Manager::get_singleton_lock (ACE_Thread_Mutex *&lock)
00443 {
00444   if (lock == 0)
00445     {
00446       if (starting_up () || shutting_down ())
00447         {
00448           // The Object_Manager and its internal lock have not been
00449           // constructed yet.  Therefore, the program is single-
00450           // threaded at this point.  Or, the ACE_Object_Manager
00451           // instance has been destroyed, so the internal lock is not
00452           // available.  Either way, we can not use double-checked
00453           // locking.  So, we'll leak the lock.
00454           ACE_NEW_RETURN (lock,
00455                           ACE_Thread_Mutex,
00456                           -1);
00457         }
00458       else
00459         {
00460           // Allocate a new lock, but use double-checked locking to
00461           // ensure that only one thread allocates it.
00462           ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00463                                     ace_mon,
00464                                     *ACE_Object_Manager::instance ()->
00465                                     internal_lock_,
00466                                     -1));
00467 
00468           if (lock == 0)
00469             {
00470               ACE_Cleanup_Adapter<ACE_Thread_Mutex> *lock_adapter;
00471               ACE_NEW_RETURN (lock_adapter,
00472                               ACE_Cleanup_Adapter<ACE_Thread_Mutex>,
00473                               -1);
00474               lock = &lock_adapter->object ();
00475 
00476               // Register the lock for destruction at program
00477               // termination.  This call will cause us to grab the
00478               // ACE_Object_Manager::instance ()->internal_lock_
00479               // again; that's why it is a recursive lock.
00480               ACE_Object_Manager::at_exit (lock_adapter);
00481             }
00482         }
00483     }
00484 
00485   return 0;
00486 }
00487 
00488 int
00489 ACE_Object_Manager::get_singleton_lock (ACE_Mutex *&lock)
00490 {
00491   if (lock == 0)
00492     {
00493       if (starting_up ()  ||  shutting_down ())
00494         {
00495           // The Object_Manager and its internal lock have not been
00496           // constructed yet.  Therefore, the program is single-
00497           // threaded at this point.  Or, the ACE_Object_Manager
00498           // instance has been destroyed, so the internal lock is not
00499           // available.  Either way, we can not use double-checked
00500           // locking.  So, we'll leak the lock.
00501 
00502           ACE_NEW_RETURN (lock,
00503                           ACE_Mutex,
00504                           -1);
00505         }
00506       else
00507         {
00508           // Allocate a new lock, but use double-checked locking to
00509           // ensure that only one thread allocates it.
00510           ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00511                                     ace_mon,
00512                                     *ACE_Object_Manager::instance ()->
00513                                       internal_lock_,
00514                                     -1));
00515 
00516           if (lock == 0)
00517             {
00518               ACE_Cleanup_Adapter<ACE_Mutex> *lock_adapter;
00519               ACE_NEW_RETURN (lock_adapter,
00520                               ACE_Cleanup_Adapter<ACE_Mutex>,
00521                               -1);
00522               lock = &lock_adapter->object ();
00523 
00524               // Register the lock for destruction at program
00525               // termination.  This call will cause us to grab the
00526               // ACE_Object_Manager::instance ()->internal_lock_
00527               // again; that's why it is a recursive lock.
00528               ACE_Object_Manager::at_exit (lock_adapter);
00529             }
00530         }
00531     }
00532 
00533   return 0;
00534 }
00535 
00536 int
00537 ACE_Object_Manager::get_singleton_lock (ACE_Recursive_Thread_Mutex *&lock)
00538 {
00539   if (starting_up ()  ||  shutting_down ())
00540     {
00541       // The preallocated lock has not been constructed yet.
00542       // Therefore, the program is single-threaded at this point.  Or,
00543       // the ACE_Object_Manager instance has been destroyed, so the
00544       // preallocated lock is not available.  Allocate a lock to use,
00545       // for interface compatibility, though there should be no
00546       // contention on it.
00547       if (ACE_Object_Manager::instance ()->singleton_recursive_lock_ == 0)
00548         ACE_NEW_RETURN (ACE_Object_Manager::instance ()->
00549                           singleton_recursive_lock_,
00550                         ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>,
00551                         -1);
00552 
00553       // Can't register with the ACE_Object_Manager here!  The lock's
00554       // declaration is visible to the ACE_Object_Manager destructor,
00555       // so it will clean it up as a special case.
00556 
00557       if (ACE_Object_Manager::instance ()->singleton_recursive_lock_ != 0)
00558         lock = &ACE_Object_Manager::instance ()->singleton_recursive_lock_->
00559           object ();
00560     }
00561   else
00562     {
00563       // Use the Object_Manager's preallocated lock.
00564       lock = ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::
00565         get_preallocated_object (ACE_Object_Manager::
00566                                  ACE_SINGLETON_RECURSIVE_THREAD_LOCK);
00567     }
00568 
00569   return 0;
00570 }
00571 
00572 int
00573 ACE_Object_Manager::get_singleton_lock (ACE_RW_Thread_Mutex *&lock)
00574 {
00575   if (lock == 0)
00576     {
00577       if (starting_up () || shutting_down ())
00578         {
00579           // The Object_Manager and its internal lock have not been
00580           // constructed yet.  Therefore, the program is single-
00581           // threaded at this point.  Or, the ACE_Object_Manager
00582           // instance has been destroyed, so the internal lock is not
00583           // available.  Either way, we can not use double-checked
00584           // locking.  So, we'll leak the lock.
00585 
00586           ACE_NEW_RETURN (lock,
00587                           ACE_RW_Thread_Mutex,
00588                           -1);
00589         }
00590       else
00591         {
00592           // Allocate a new lock, but use double-checked locking to
00593           // ensure that only one thread allocates it.
00594           ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00595                                     ace_mon,
00596                                     *ACE_Object_Manager::instance ()->
00597                                     internal_lock_,
00598                                     -1));
00599 
00600           if (lock == 0)
00601             {
00602               ACE_Cleanup_Adapter<ACE_RW_Thread_Mutex> *lock_adapter;
00603               ACE_NEW_RETURN (lock_adapter,
00604                               ACE_Cleanup_Adapter<ACE_RW_Thread_Mutex>,
00605                               -1);
00606               lock = &lock_adapter->object ();
00607 
00608 
00609               // Register the lock for destruction at program
00610               // termination.  This call will cause us to grab the
00611               // ACE_Object_Manager::instance ()->internal_lock_
00612               // again; that's why it is a recursive lock.
00613               ACE_Object_Manager::at_exit (lock_adapter);
00614             }
00615         }
00616     }
00617 
00618   return 0;
00619 }
00620 #endif /* ACE_MT_SAFE */
00621 
00622 // Clean up an ACE_Object_Manager.  There can be instances of this object
00623 // other than The Instance.  This can happen if (on Win32) the ACE DLL
00624 // causes one to be created, or if a user creates one for some reason.
00625 // Only The Instance cleans up the static preallocated objects.  All objects
00626 // clean up their per-object information and managed objects.
00627 int
00628 ACE_Object_Manager::fini (void)
00629 {
00630   if (shutting_down_i ())
00631     // Too late.  Or, maybe too early.  Either fini () has already
00632     // been called, or init () was never called.
00633     return object_manager_state_ == OBJ_MAN_SHUT_DOWN  ?  1  :  -1;
00634 
00635   // No mutex here.  Only the main thread should destroy the singleton
00636   // ACE_Object_Manager instance.
00637 
00638   // Indicate that this ACE_Object_Manager instance is being
00639   // shut down.
00640   object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
00641 
00642   // Call all registered cleanup hooks, in reverse order of
00643   // registration.
00644   exit_info_.call_hooks ();
00645 
00646   if (this == instance_)
00647     {
00648 #if !defined (ACE_LACKS_ACE_SVCCONF)
00649       delete preallocations_;
00650       preallocations_ = 0;
00651 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00652 
00653 #if defined (ACE_HAS_TRACE)
00654       ACE_Trace::stop_tracing ();
00655 #endif /* ACE_HAS_TRACE */
00656 
00657 #if !defined (ACE_LACKS_ACE_SVCCONF)
00658       // Close and possibly delete all service instances in the Service
00659       // Repository.
00660       ACE_Service_Config::fini_svcs ();
00661 
00662       // Unlink all services in the Service Repository and close/delete
00663       // all ACE library services and singletons.
00664       ACE_Service_Config::close ();
00665 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00666 
00667       // This must come after closing ACE_Service_Config, since it will
00668       // close down it's dlls--it manages ACE_DLL_Manager.
00669       ACE_Framework_Repository::close_singleton ();
00670       ACE_DLL_Manager::close_singleton ();
00671 
00672 #  if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00673       ACE_Thread_Manager::close_singleton ();
00674 #  endif /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
00675 
00676       // Close the main thread's TSS, including its Log_Msg instance.
00677       ACE_OS::cleanup_tss (1 /* main thread */);
00678 
00679       //
00680       // Note:  Do not access Log Msg after this since it is gone
00681       //
00682 
00683       // Close the ACE_Allocator.
00684       ACE_Allocator::close_singleton ();
00685 
00686 #if ! defined (ACE_HAS_STATIC_PREALLOCATION)
00687       // Hooks for deletion of preallocated objects and arrays provided by
00688       // application.
00689       ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS
00690       ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS
00691 
00692       // Cleanup the dynamically preallocated arrays.
00693       // (none)
00694 
00695       // Cleanup the dynamically preallocated objects.
00696       ACE_DELETE_PREALLOCATED_OBJECT (ACE_SYNCH_RW_MUTEX, ACE_FILECACHE_LOCK)
00697 #if defined (ACE_HAS_THREADS)
00698       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
00699                                       ACE_STATIC_OBJECT_LOCK)
00700 #endif /* ACE_HAS_THREADS */
00701 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00702       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex,
00703                                       ACE_MT_CORBA_HANDLER_LOCK)
00704       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK)
00705       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
00706                                       ACE_SIG_HANDLER_LOCK)
00707       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Null_Mutex,
00708                                       ACE_SINGLETON_NULL_LOCK)
00709       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Recursive_Thread_Mutex,
00710                                       ACE_SINGLETON_RECURSIVE_THREAD_LOCK)
00711       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_THREAD_EXIT_LOCK)
00712 #if !defined (ACE_LACKS_ACE_TOKEN) && defined (ACE_HAS_TOKENS_LIBRARY)
00713       ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX,
00714                                       ACE_TOKEN_MANAGER_CREATION_LOCK)
00715       ACE_DELETE_PREALLOCATED_OBJECT (ACE_TOKEN_CONST::MUTEX,
00716                                       ACE_TOKEN_INVARIANTS_CREATION_LOCK)
00717 #endif /* ! ACE_LACKS_ACE_TOKEN && ACE_HAS_TOKENS_LIBRARY */
00718       ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex,
00719                                       ACE_PROACTOR_EVENT_LOOP_LOCK)
00720 # endif /* ACE_MT_SAFE */
00721 #endif /* ! ACE_HAS_STATIC_PREALLOCATION */
00722 
00723 #if defined (ACE_HAS_THREADS)
00724       ACE_Static_Object_Lock::cleanup_lock ();
00725 #endif /* ACE_HAS_THREADS */
00726     }
00727 
00728 #if !defined (ACE_LACKS_ACE_SVCCONF)
00729   delete ace_service_config_sig_handler_;
00730   ace_service_config_sig_handler_ = 0;
00731 #endif /* ! ACE_LACKS_ACE_SVCCONF */
00732 
00733 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00734   delete internal_lock_;
00735   internal_lock_ = 0;
00736 
00737   delete singleton_null_lock_;
00738   singleton_null_lock_ = 0;
00739 
00740   delete singleton_recursive_lock_;
00741   singleton_recursive_lock_ = 0;
00742 #endif /* ACE_MT_SAFE */
00743 
00744   // Indicate that this ACE_Object_Manager instance has been shut down.
00745   object_manager_state_ = OBJ_MAN_SHUT_DOWN;
00746 
00747   // Then, ensure that the ACE_OS_Object_Manager gets shut down.
00748   if (this == instance_ && ACE_OS_Object_Manager::instance_)
00749     ACE_OS_Object_Manager::instance_->fini ();
00750 
00751   if (dynamically_allocated_)
00752     {
00753       delete this;
00754     }
00755 
00756   if (this == instance_)
00757     instance_ = 0;
00758 
00759   return 0;
00760 }
00761 
00762 
00763 #if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
00764 /**
00765  * @class ACE_Object_Manager_Manager
00766  *
00767  * @brief Ensure that the ACE_Object_Manager gets initialized at program
00768  * startup, and destroyed at program termination.
00769  *
00770  * Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this
00771  * class is created.  Therefore, it gets created before main ()
00772  * is called.  And it gets destroyed after main () returns.
00773  */
00774 class ACE_Export ACE_Object_Manager_Manager
00775 {
00776 public:
00777   ACE_Object_Manager_Manager (void);
00778   ~ACE_Object_Manager_Manager (void);
00779 
00780 private:
00781   /// Save the main thread ID, so that destruction can be suppressed.
00782   ACE_thread_t saved_main_thread_id_;
00783 };
00784 
00785 ACE_Object_Manager_Manager::ACE_Object_Manager_Manager (void)
00786   : saved_main_thread_id_ (ACE_OS::thr_self ())
00787 {
00788   // Ensure that the Object_Manager gets initialized before any
00789   // application threads have been spawned.  Because this will be called
00790   // during construction of static objects, that should always be the
00791   // case.
00792   (void) ACE_Object_Manager::instance ();
00793 }
00794 
00795 ACE_Object_Manager_Manager::~ACE_Object_Manager_Manager (void)
00796 {
00797   if (ACE_OS::thr_equal (ACE_OS::thr_self (),
00798                          saved_main_thread_id_))
00799     {
00800       delete ACE_Object_Manager::instance_;
00801       ACE_Object_Manager::instance_ = 0;
00802     }
00803   // else if this destructor is not called by the main thread, then do
00804   // not delete the ACE_Object_Manager.  That causes problems, on
00805   // WIN32 at least.
00806 }
00807 
00808 static ACE_Object_Manager_Manager ACE_Object_Manager_Manager_instance;
00809 #endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */
00810 
00811 #if defined (ACE_HAS_THREADS)
00812 
00813 // hack to get around errors while compiling using split-cpp
00814 #if !defined (ACE_IS_SPLITTING)
00815 // This is global so that it doesn't have to be declared in the header
00816 // file.  That would cause nasty circular include problems.
00817 typedef ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex> ACE_Static_Object_Lock_Type;
00818 static ACE_Static_Object_Lock_Type *ACE_Static_Object_Lock_lock = 0;
00819 #endif /* ! ACE_IS_SPLITTING */
00820 
00821 // ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK isn't (currently) used by ACE.
00822 // But, applications may find it useful for avoiding recursive calls
00823 // if they have overridden operator new.  Thanks to Jody Hagins
00824 // <jody@atdesk.com> for contributing it.
00825 
00826 ACE_Recursive_Thread_Mutex *
00827 ACE_Static_Object_Lock::instance (void)
00828 {
00829   if (ACE_Object_Manager::starting_up ()  ||
00830       ACE_Object_Manager::shutting_down ())
00831     {
00832       // The preallocated ACE_STATIC_OBJECT_LOCK has not been
00833       // constructed yet.  Therefore, the program is single-threaded
00834       // at this point.  Or, the ACE_Object_Manager instance has been
00835       // destroyed, so the preallocated lock is not available.
00836       // Allocate a lock to use, for interface compatibility, though
00837       // there should be no contention on it.
00838       if (ACE_Static_Object_Lock_lock == 0)
00839         {
00840 #     if defined (ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK)
00841         // Allocate a buffer with malloc, and then use placement
00842         // new for the object, on the malloc'd buffer.
00843         void *buffer =
00844           ACE_OS::malloc (sizeof (*ACE_Static_Object_Lock_lock));
00845         if (buffer == 0)
00846           {
00847             return 0;
00848           }
00849         // do not use ACE_NEW macros for placement new
00850         ACE_Static_Object_Lock_lock = new (buffer)
00851                         ACE_Static_Object_Lock_Type ();
00852 
00853 #       else   /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
00854         ACE_NEW_RETURN (ACE_Static_Object_Lock_lock,
00855                         ACE_Cleanup_Adapter<ACE_Recursive_Thread_Mutex>,
00856                         0);
00857 #       endif /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
00858         }
00859 
00860       // Can't register with the ACE_Object_Manager here!  The lock's
00861       // declaration is visible to the ACE_Object_Manager destructor,
00862       // so it will clean it up as a special case.
00863 
00864       return &ACE_Static_Object_Lock_lock->object ();
00865     }
00866   else
00867     // Return the preallocated ACE_STATIC_OBJECT_LOCK.
00868     return
00869       ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00870         (ACE_Object_Manager::ACE_STATIC_OBJECT_LOCK);
00871 }
00872 
00873 void
00874 ACE_Static_Object_Lock::cleanup_lock (void)
00875 {
00876 # if defined(ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK)
00877     // It was malloc'd, so we need to explicitly call the dtor
00878     // and then free the memory.
00879     ACE_DES_FREE (ACE_Static_Object_Lock_lock,
00880                   ACE_OS::free,
00881                   ACE_Static_Object_Lock_Type);
00882 # else  /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
00883     delete ACE_Static_Object_Lock_lock;
00884 # endif /* ! ACE_SHOULD_MALLOC_STATIC_OBJECT_LOCK */
00885     ACE_Static_Object_Lock_lock = 0;
00886 }
00887 #endif /* ACE_HAS_THREADS */
00888 
00889 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7