Object_Manager.cpp

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

Generated on Thu Nov 9 09:41:57 2006 for ACE by doxygen 1.3.6