Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Object_Manager.cpp

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

Generated on Mon Jun 16 11:20:30 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002