diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-20 22:32:07 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-20 22:32:07 +0000 |
commit | 5ee93a4dba1542ad8d2136ba0ffb389bbefc16b0 (patch) | |
tree | dfedd325947bec8380259bf875c36a9f61a4a574 | |
parent | 7ed16425b8bed4d147fa7eb2ad8434de100fbc5a (diff) | |
download | ATCD-5ee93a4dba1542ad8d2136ba0ffb389bbefc16b0.tar.gz |
revised ACE_Object_Manager interface for preallocated objects
-rw-r--r-- | ace/CORBA_Handler.cpp | 62 | ||||
-rw-r--r-- | ace/CORBA_Handler.h | 21 | ||||
-rw-r--r-- | ace/Dump.cpp | 13 | ||||
-rw-r--r-- | ace/Dump.h | 5 | ||||
-rw-r--r-- | ace/Log_Msg.cpp | 6 | ||||
-rw-r--r-- | ace/Managed_Object.cpp | 42 | ||||
-rw-r--r-- | ace/Managed_Object.h | 60 | ||||
-rw-r--r-- | ace/Managed_Object.i | 52 | ||||
-rw-r--r-- | ace/OS.cpp | 56 | ||||
-rw-r--r-- | ace/Object_Manager.cpp | 104 | ||||
-rw-r--r-- | ace/Object_Manager.h | 154 |
11 files changed, 390 insertions, 185 deletions
diff --git a/ace/CORBA_Handler.cpp b/ace/CORBA_Handler.cpp index 4a859d0a657..50a6776deb5 100644 --- a/ace/CORBA_Handler.cpp +++ b/ace/CORBA_Handler.cpp @@ -173,9 +173,9 @@ ACE_ST_CORBA_Handler::ACE_ST_CORBA_Handler (void) // Set up the callbacks so that we get informed when Orbix changes // its descriptors. ACE_CORBA_1 (Orbix.registerIOCallback) ((OrbixIOCallback) &ACE_ST_CORBA_Handler::insert_handle, - FD_OPEN_CALLBACK); + FD_OPEN_CALLBACK); ACE_CORBA_1 (Orbix.registerIOCallback) ((OrbixIOCallback) &ACE_ST_CORBA_Handler::remove_handle, - FD_CLOSE_CALLBACK); + FD_CLOSE_CALLBACK); } void @@ -199,8 +199,8 @@ ACE_ST_CORBA_Handler::get_orbix_descriptors (void) /* static */ int ACE_CORBA_Handler::register_service (const char *service_name, - const char *marker_name, - const char *service_location) + const char *marker_name, + const char *service_location) { ACE_TRACE ("ACE_CORBA_Handler::register_service"); char buf[BUFSIZ * 2]; // I hope this is enough space... @@ -215,7 +215,7 @@ ACE_CORBA_Handler::register_service (const char *service_name, ACE_OS::sprintf (buf, "putit %s %s", service_name, service_location); else ACE_OS::sprintf (buf, "putit -marker %s %s %s", - marker_name, service_name, service_location); + marker_name, service_name, service_location); return ACE_OS::system (buf); // Use system(3S) to execute Orbix putit. } @@ -226,7 +226,7 @@ ACE_CORBA_Handler::register_service (const char *service_name, /* static */ int ACE_CORBA_Handler::remove_service (const char *service_name, - const char *marker_name) + const char *marker_name) { ACE_TRACE ("ACE_CORBA_Handler::remove_service"); char buf[BUFSIZ * 2]; // I hope this is enough space! @@ -268,7 +268,7 @@ ACE_ST_CORBA_Handler::~ACE_ST_CORBA_Handler (void) /* static */ int ACE_CORBA_Handler::deactivate_service (const char *service_name, - const char *marker_name) + const char *marker_name) { ACE_TRACE ("ACE_CORBA_Handler::deactivate_service"); if (service_name != 0 @@ -316,8 +316,8 @@ ACE_ST_CORBA_Handler::instance (void) int ACE_CORBA_Handler::activate_service (const char *service_name, - const char *marker_name, - const char *service_location) + const char *marker_name, + const char *service_location) { ACE_TRACE ("ACE_CORBA_Handler::activate_service"); // Since the ACE_CORBA_Handler is a singleton, make sure not to @@ -328,7 +328,7 @@ ACE_CORBA_Handler::activate_service (const char *service_name, if (service_name != 0 && service_location != 0 && this->register_service (service_name, marker_name, - service_location) == -1) + service_location) == -1) return -1; // Tell Orbix that we have completed the server's initialization. @@ -347,12 +347,6 @@ ACE_CORBA_Handler::activate_service (const char *service_name, ACE_ALLOC_HOOK_DEFINE(ACE_MT_CORBA_Handler) -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) -// Synchronize output operations. -u_int ACE_MT_CORBA_Handler::ace_mt_corba_handler_lock_ = - ACE_Object_Manager::ACE_MT_CORBA_HANDLER_LOCK; -#endif /* ACE_MT_SAFE */ - void ACE_MT_CORBA_Handler::dump (void) const { @@ -363,9 +357,9 @@ ACE_MT_CORBA_Handler::dump (void) const ACE_DEBUG ((LM_DEBUG, "\nthr_mgr_ = %x", this->thr_mgr_)); this->pipe_.dump (); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - // Double-Check lock. - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_mt_corba_handler_lock_); + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_MT_CORBA_HANDLER_LOCK); if (lock != 0) lock->dump (); #endif /* ACE_MT_SAFE */ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); @@ -384,15 +378,15 @@ ACE_MT_CORBA_Handler::instance (void) if (ACE_MT_CORBA_Handler::instance_ == 0) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_mt_corba_handler_lock_); - if (lock == 0) return 0; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_MT_CORBA_HANDLER_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ if (ACE_MT_CORBA_Handler::instance_ == 0) - ACE_NEW_RETURN (ACE_MT_CORBA_Handler::instance_, - ACE_MT_CORBA_Handler, 0); + ACE_NEW_RETURN (ACE_MT_CORBA_Handler::instance_, + ACE_MT_CORBA_Handler, 0); } return ACE_MT_CORBA_Handler::instance_; @@ -438,7 +432,7 @@ ACE_MT_CORBA_Handler::ACE_MT_CORBA_Handler (void) // Create a new thread that processes events for the Orbix event // queue. else if (this->thr_mgr ()->spawn (ACE_THR_FUNC (ACE_MT_CORBA_Handler::process_events), - 0, THR_DETACHED | THR_NEW_LWP) == -1) + 0, THR_DETACHED | THR_NEW_LWP) == -1) result = -1; if (result == -1) @@ -460,10 +454,10 @@ ACE_MT_CORBA_Handler::process_events (void *) if (ACE_MT_CORBA_Handler::instance_ == 0) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_mt_corba_handler_lock_); - if (lock == 0) return 0; - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock, 0); + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_MT_CORBA_HANDLER_LOCK); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ ACE_ASSERT (ACE_MT_CORBA_Handler::instance_ != 0); @@ -486,7 +480,7 @@ ACE_MT_CORBA_Handler::process_events (void *) int ACE_MT_CORBA_Handler::inRequestPreMarshal (ACE_CORBA_1 (Request) &req, - ACE_CORBA_1 (Environment) &IT_env) + ACE_CORBA_1 (Environment) &IT_env) { ACE_TRACE ("ACE_MT_CORBA_Handler::inRequestPreMarshal"); @@ -494,8 +488,8 @@ ACE_MT_CORBA_Handler::inRequestPreMarshal (ACE_CORBA_1 (Request) &req, u_long request_addr = (u_long) &req; ssize_t result = ACE::send (this->pipe_.write_handle (), - (const char *) &request_addr, - sizeof request_addr); + (const char *) &request_addr, + sizeof request_addr); if (result != sizeof request_addr) { @@ -518,8 +512,8 @@ ACE_MT_CORBA_Handler::handle_input (ACE_HANDLE) // Read the request from the pipe. ssize_t result = ACE::recv (this->pipe_.read_handle (), - (char *) &request_addr, - sizeof request_addr); + (char *) &request_addr, + sizeof request_addr); if (result != sizeof request_addr) // We are in trouble: bail out. diff --git a/ace/CORBA_Handler.h b/ace/CORBA_Handler.h index 7b280759308..ec9439a1227 100644 --- a/ace/CORBA_Handler.h +++ b/ace/CORBA_Handler.h @@ -53,16 +53,16 @@ public: // = Activation and deactivation methods. virtual int activate_service (const char *service_name, - const char *marker_name = 0, - const char *service_location = 0); + const char *marker_name = 0, + const char *service_location = 0); // Activate and register <service_name> with the Orbix daemon. If // <marker_name> and <service_location> are != 0 then do a "putit" // to register this service with orbixd. This method also // increments the reference count of active services using the // ACE_ST_CORBA_Handler. - + virtual int deactivate_service (const char *service_name = 0, - const char *marker_name = 0); + const char *marker_name = 0); // Decrement the reference count and free up all the // resources if this is the last service to be using // the ACE_ST_CORBA_Handler... @@ -87,14 +87,14 @@ protected: // Note virtual destructor... virtual int register_service (const char *service_name, - const char *marker_name, - const char *service_location); + const char *marker_name, + const char *service_location); // Register <service_name> by doing a "putit" to register // the <service_name> using the <marker_name> at <service_location> // with orbixd. virtual int remove_service (const char *service_name, - const char *marker_name = 0); + const char *marker_name = 0); // Register <service_name> by doing a "putit" to register // <service_name> using the <marker_name> with orbixd. @@ -215,7 +215,7 @@ protected: // Destructor cleans up resources. virtual int inRequestPreMarshal (ACE_CORBA_1 (Request) &r, - ACE_CORBA_1 (Environment) &IT_env = ACE_CORBA_1 (default_environment)); + ACE_CORBA_1 (Environment) &IT_env = ACE_CORBA_1 (default_environment)); // Take the incoming request and pass it to this->handle_input() but // through the Reactor. @@ -227,11 +227,6 @@ protected: ACE_Pipe pipe_; // Used to send CORBA::Requests through the server - -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - static u_int ace_mt_corba_handler_lock_; - // Double-Check lock identifier. -#endif /* ACE_MT_SAFE */ }; #endif /* ACE_HAS_MT_ORBIX */ diff --git a/ace/Dump.cpp b/ace/Dump.cpp index 26e404195ec..755d36aba9e 100644 --- a/ace/Dump.cpp +++ b/ace/Dump.cpp @@ -6,11 +6,6 @@ #include "ace/Dump.h" #include "ace/Object_Manager.h" -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) -// Synchronize output operations. -u_int ACE_ODB::ace_dump_lock_ = ACE_Object_Manager::ACE_DUMP_LOCK; -#endif /* ACE_MT_SAFE */ - // Implementations (very simple for now...) ACE_Dumpable::~ACE_Dumpable (void) @@ -61,14 +56,14 @@ ACE_ODB::instance (void) if (ACE_ODB::instance_ == 0) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ACE_ODB::ace_dump_lock_); - if (lock == 0) return 0; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_DUMP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ if (ACE_ODB::instance_ == 0) - ACE_NEW_RETURN (ACE_ODB::instance_, ACE_ODB, 0); + ACE_NEW_RETURN (ACE_ODB::instance_, ACE_ODB, 0); } return ACE_ODB::instance_; diff --git a/ace/Dump.h b/ace/Dump.h index ab1f2053a95..5217e42bfb2 100644 --- a/ace/Dump.h +++ b/ace/Dump.h @@ -142,11 +142,6 @@ private: int current_size_; // Current size of <object_table_>. - -#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - static u_int ace_dump_lock_; - // Double-Check lock identifier. -#endif /* ACE_MT_SAFE */ }; // Include the templates classes at this point. diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp index d453d78a486..3b462214e68 100644 --- a/ace/Log_Msg.cpp +++ b/ace/Log_Msg.cpp @@ -1,4 +1,3 @@ -// Log_Msg.cpp // $Id$ #define ACE_BUILD_DLL @@ -177,10 +176,9 @@ ACE_Log_Msg::instance (void) if (ACE_Log_Msg_key_created_ == 0) { - static ACE_Thread_Mutex *lock = - ACE_Managed_Object<ACE_Thread_Mutex>::get_object + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object (ACE_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK); - if (lock == 0) return 0; ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0); diff --git a/ace/Managed_Object.cpp b/ace/Managed_Object.cpp index f36f7014d87..5ca197c1383 100644 --- a/ace/Managed_Object.cpp +++ b/ace/Managed_Object.cpp @@ -11,18 +11,9 @@ # include "ace/Synch.h" #endif /* !ACE_TEMPLATES_REQUIRE_SOURCE */ -template <class TYPE> -ACE_Managed_Cleanup<TYPE>::ACE_Managed_Cleanup (void) - : object_ () -{ -} - -template <class TYPE> -TYPE & -ACE_Managed_Cleanup<TYPE>::object (void) -{ - return this->object_; -} +#if !defined (__ACE_INLINE__) +#include "ace/Managed_Object.i" +#endif /* __ACE_INLINE__ */ template <class TYPE> int @@ -46,7 +37,7 @@ ACE_Managed_Object<TYPE>::get_object (int &id, TYPE *&object) } else { - id = ACE_Object_Manager::next_managed_object; + id = ACE_Object_Manager::next_managed_object + 1; ACE_Object_Manager::managed_object[ ACE_Object_Manager::next_managed_object++] = object; return 0; @@ -60,7 +51,7 @@ ACE_Managed_Object<TYPE>::get_object (int &id, TYPE *&object) return -1; } } - else if (id < 0 || (u_int) id >= ACE_Object_Manager::next_managed_object) + else if (id < 0 || (u_int) id > ACE_Object_Manager::next_managed_object) { // Unknown, non-zero, or negative id. object = 0; @@ -76,27 +67,4 @@ ACE_Managed_Object<TYPE>::get_object (int &id, TYPE *&object) } } -template <class TYPE> -TYPE * -ACE_Managed_Object<TYPE>::get_object (int id) -{ - // Use the ACE_Object_Manager instance's lock. - ACE_MT (ACE_Thread_Mutex &lock = *ACE_Object_Manager::instance ()->lock_); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock, 0)); - - if (id <= 0 || (u_int) id > ACE_Object_Manager::next_managed_object) - { - // Unknown or invalid managed object id. - errno = ENOENT; - return 0; - } - else - { - // id is known, so return the object. Cast its type based - // on the type of the function template parameter. - return &((ACE_Managed_Cleanup<TYPE> *) - ACE_Object_Manager::managed_object[id - 1])->object (); - } -} - #endif /* ACE_MANAGED_OBJECT_CPP */ diff --git a/ace/Managed_Object.h b/ace/Managed_Object.h index 925986191cf..449da574bd7 100644 --- a/ace/Managed_Object.h +++ b/ace/Managed_Object.h @@ -21,6 +21,14 @@ template <class TYPE> class ACE_Managed_Cleanup : public ACE_Cleanup + // = TITLE + // Adapter for ACE_Cleanup objects that allows them to be readily + // managed by the ACE_Object_Manager. + // + // = DESCRIPTION + // This template class wraps adapts an object of any type to be + // an ACE_Cleanup object. It can then be destroyed type-safely + // by the ACE_Object_Manager. { public: ACE_Managed_Cleanup (void); @@ -60,6 +68,29 @@ class ACE_Managed_Object // return the pointer to the identified object. The caller is // responsible for ensuring type safety by not casting the pointer // that it holds in calls to get_object (). + // + // get_preallocated_object () accesses a "preallocated" object, + // i.e., one that is identified by a value in the + // ACE_Object_Manager:: Preallocated_Object enum. These + // objects are used internally by the ACE library. + // + // Hooks are provided for the application to preallocate objects + // via the same mechanism. + // ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS can be used + // to define enum values; + // ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS can be used + // to define the corresponding objects. The format of the ACE + // internal library definitions should be followed. And similarly, + // ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS and + // ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS can be used to + // preallocate arrays. + // + // By default, preallocation uses dynamic allocation. The + // preallocated objects and arrays are allocated off the heap in + // the ACE_Object_Manager constructor. The statically place the + // preallocated objects in program global data instead of on the + // heap, #define ACE_HAS_STATIC_PREALLOCATION prior to building + // the ACE library. { public: static int get_object (int &id, TYPE *&object); @@ -71,13 +102,32 @@ public: // ENOSPC if no more table slots are available: see the // ACE_MAX_MANAGED_OBJECTS config variable. - static TYPE *get_object (int id); - // Get the object identified by "id". Returns a pointer to the - // object, or 0 if any error was encountered (and sets errno to - // ENOENT). Because no other error indication is provided, it - // should _only_ be used for accessing preallocated objects. + static + TYPE *get_preallocated_object (ACE_Object_Manager::Preallocated_Object id); + // Get the preallocated object identified by "id". Returns a + // pointer to the object. Beware: no error indication is provided, + // because it can _only_ be used for accessing preallocated objects. + + static + TYPE *get_preallocated_array (ACE_Object_Manager::Preallocated_Array id); + // Get the preallocated array identified by "id". Returns a + // pointer to the array. Beware: no error indication is provided, + // because it can _only_ be used for accessing preallocated arrays. + +private: + // Disallow instantiation of this class. + ACE_UNIMPLEMENTED_FUNC (ACE_Managed_Object ()) + ACE_UNIMPLEMENTED_FUNC (ACE_Managed_Object (const ACE_Managed_Object &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Managed_Object &operator= + (const ACE_Managed_Object &)) + + friend class this_prevents_compiler_warning_about_only_private_constructors; }; +#if defined (__ACE_INLINE__) +#include "ace/Managed_Object.i" +#endif /* __ACE_INLINE__ */ + #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) #include "ace/Managed_Object.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ diff --git a/ace/Managed_Object.i b/ace/Managed_Object.i new file mode 100644 index 00000000000..9c38a7542c5 --- /dev/null +++ b/ace/Managed_Object.i @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + +// Note: don't explicitly initialize "object_", because TYPE may not +// have a default constructor. Let the compiler figure it out . . . +template <class TYPE> +ACE_INLINE +ACE_Managed_Cleanup<TYPE>::ACE_Managed_Cleanup (void) +{ +} + +template <class TYPE> +ACE_INLINE +TYPE & +ACE_Managed_Cleanup<TYPE>::object (void) +{ + return this->object_; +} + +template <class TYPE> +ACE_INLINE +TYPE * +ACE_Managed_Object<TYPE>::get_preallocated_object + (ACE_Object_Manager::Preallocated_Object id) +{ + // The preallocated objects are in a separate, "read-only" array so + // that this function doesn't need a lock. Also, because it is + // intended _only_ for use with hard-code values, it performs no + // range checking on "id". + + // Cast the return type of the the object pointer based + // on the type of the function template parameter. + return &((ACE_Managed_Cleanup<TYPE> *) + ACE_Object_Manager::preallocated_object[id])->object (); +} + +template <class TYPE> +ACE_INLINE +TYPE * +ACE_Managed_Object<TYPE>::get_preallocated_array + (ACE_Object_Manager::Preallocated_Array id) +{ + // The preallocated array are in a separate, "read-only" array so + // that this function doesn't need a lock. Also, because it is + // intended _only_ for use with hard-code values, it performs no + // range checking on "id". + + // Cast the return type of the the object pointer based + // on the type of the function template parameter. + return &((ACE_Managed_Cleanup<TYPE> *) + ACE_Object_Manager::preallocated_array[id])->object (); +} diff --git a/ace/OS.cpp b/ace/OS.cpp index 103e554c0d7..7accf878556 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -25,9 +25,6 @@ // This is lock defines a monitor that is shared by all threads // calling certain ACE_OS methods. static ACE_Thread_Mutex ace_os_monitor_lock; -#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) - static u_int ace_tss_cleanup_lock = ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK; -#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */ #if defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) int @@ -974,7 +971,7 @@ public: // Free all key left in the table before destruct myself. static int lockable () { return instance_ != 0; } - // Indication of whether the ace_tss_cleanup_lock is usable, and + // Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and // therefore whether we are in static constructor/destructor phase // or not. @@ -1040,7 +1037,9 @@ ACE_TSS_Cleanup::exit (void * /* status */) // ACE_TRACE ("ACE_TSS_Cleanup::exit"); // ACE_thread_key_t key_arr[ACE_DEFAULT_THREAD_KEYS]; +#if 0 int index = 0; +#endif /* 0 */ ACE_TSS_Info *key_info = 0; ACE_TSS_Info info_arr[ACE_DEFAULT_THREAD_KEYS]; @@ -1051,9 +1050,9 @@ ACE_TSS_Cleanup::exit (void * /* status */) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD (ACE_Thread_Mutex, ace_mon, *lock); #endif /* ACE_MT_SAFE */ @@ -1120,9 +1119,9 @@ ACE_TSS_Cleanup::exit (void * /* status */) // entries from ACE_TSS_Info table. { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD (ACE_Thread_Mutex, ace_mon, *lock); #endif /* ACE_MT_SAFE */ @@ -1185,9 +1184,9 @@ ACE_TSS_Cleanup::instance (void) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) // Insure that we are serialized! - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return 0; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0); #endif /* ACE_MT_SAFE */ @@ -1207,9 +1206,9 @@ ACE_TSS_Cleanup::insert (ACE_thread_key_t key, { // ACE_TRACE ("ACE_TSS_Cleanup::insert"); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return -1; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, -1); #endif /* ACE_MT_SAFE */ @@ -1221,9 +1220,9 @@ ACE_TSS_Cleanup::remove (ACE_thread_key_t key) { // ACE_TRACE ("ACE_TSS_Cleanup::remove"); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return -1; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, -1); #endif /* ACE_MT_SAFE */ @@ -1234,9 +1233,9 @@ int ACE_TSS_Cleanup::detach (void *inst) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return -1; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, -1); #endif /* ACE_MT_SAFE */ @@ -1285,9 +1284,9 @@ int ACE_TSS_Cleanup::key_used (ACE_thread_key_t key) { #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_Thread_Mutex *lock = ACE_Managed_Object<ACE_Thread_Mutex>::get_object - (ace_tss_cleanup_lock); - if (lock == 0) return -1; + ACE_Thread_Mutex *lock = + ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object + (ACE_Object_Manager::ACE_TSS_CLEANUP_LOCK); ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, -1); #endif /* ACE_MT_SAFE */ @@ -2633,8 +2632,11 @@ int sys_nerr = ERRMAX + 1; #include /**/ <usrLib.h> /* for ::sp() */ // This global function can be used from the VxWorks shell to pass -// arguments to a C main () function. usage: -> spa main, "arg1", -// "arg2" All arguments must be quoted, even numbers. +// arguments to a C main () function. +// +// usage: -> spa main, "arg1", "arg2" +// +// All arguments must be quoted, even numbers. int spa (FUNCPTR entry, ...) { diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp index 6011dd84352..bc0e8d7de3a 100644 --- a/ace/Object_Manager.cpp +++ b/ace/Object_Manager.cpp @@ -12,24 +12,77 @@ #include "ace/Object_Manager.i" #endif /* __ACE_INLINE__ */ -// Singleton pointer. +#if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS) +# define ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS +#endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS */ + +#if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS) +# define ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS +#endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS */ + +#if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS) +# define ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS +#endif /* ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS */ + +#if ! defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS) +# define ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS +#endif /* ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS */ + +// Static data. ACE_Object_Manager *ACE_Object_Manager::instance_ = 0; void *ACE_Object_Manager::managed_object[ACE_MAX_MANAGED_OBJECTS] = { 0 }; u_int ACE_Object_Manager::next_managed_object = 0; -// Handy macro for use by ACE_Object_Manager constructor to preallocate -// an object. -#define ACE_PREALLOCATE_OBJECT(TYPE, ID) \ - { \ - ACE_Managed_Cleanup<TYPE> *obj_p; \ - ACE_NEW (obj_p, ACE_Managed_Cleanup<TYPE>); \ - managed_object[ID - 1] = obj_p; \ - } +void *ACE_Object_Manager::preallocated_object[ + ACE_Object_Manager::ACE_PREALLOCATED_OBJECTS] = { 0 }; + +void *ACE_Object_Manager::preallocated_array[ + ACE_Object_Manager::ACE_PREALLOCATED_ARRAYS] = { 0 }; + +// Handy macros for use by ACE_Object_Manager constructor to preallocate or +// delete an object or array, either statically (in global data) or +// dynamically (on the heap). +#if defined (ACE_HAS_STATIC_PREALLOCATION) +# define ACE_PREALLOCATE_OBJECT(TYPE, ID)\ + {\ + static ACE_Managed_Cleanup<TYPE> obj;\ + preallocated_object[ID] = &obj;\ + } +# define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\ + {\ + static ACE_Managed_Cleanup<TYPE> obj[COUNT];\ + preallocated_array[ID] = &obj;\ + } +#else +# define ACE_PREALLOCATE_OBJECT(TYPE, ID)\ + {\ + ACE_Managed_Cleanup<TYPE> *obj_p;\ + ACE_NEW (obj_p, ACE_Managed_Cleanup<TYPE>);\ + preallocated_object[ID] = obj_p;\ + } +# define ACE_PREALLOCATE_ARRAY(TYPE, ID, COUNT)\ + {\ + ACE_Managed_Cleanup<TYPE> *obj_p;\ + ACE_NEW (obj_p, ACE_Managed_Cleanup<TYPE>[COUNT]);\ + preallocated_array[ID] = obj_p;\ + } +# define ACE_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\ + ace_cleanup_destroyer (\ + (ACE_Managed_Cleanup<TYPE> *) preallocated_object[ID], 0);\ + preallocated_object[ID] = 0; +# define ACE_DELETE_PREALLOCATED_ARRAY(TYPE, ID)\ + delete [] (ACE_Managed_Cleanup<TYPE> *) preallocated_array[ID];\ + preallocated_array[ID] = 0; +#endif /* ACE_HAS_STATIC_PREALLOCATION */ + ACE_Object_Manager::ACE_Object_Manager (void) : shutting_down_(0) + // , lock_ is initialized in the function body. + // With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call + // to ACE_OS::tss_open () in the function body. { ACE_NEW (registered_objects_, ACE_Unbounded_Queue<ACE_Cleanup_Info>); @@ -41,8 +94,7 @@ ACE_Object_Manager::ACE_Object_Manager (void) instance_ = this; #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */ - // Allocate the preallocated (hard-coded) object instances, and - // register them for destruction. + // Allocate the preallocated (hard-coded) object instances. # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_LOG_MSG_INSTANCE_LOCK) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_MT_CORBA_HANDLER_LOCK) @@ -50,7 +102,12 @@ ACE_Object_Manager::ACE_Object_Manager (void) ACE_PREALLOCATE_OBJECT (ACE_Thread_Mutex, ACE_TSS_CLEANUP_LOCK) # endif /* ACE_MT_SAFE */ - next_managed_object = ACE_END_OF_PREALLOCATED_OBJECTS - 1; + // Allocate the preallocated (hard-coded) arrays. + // (None, yet.) + + // Hooks for preallocated objects and arrays provided by application. + ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS + ACE_APPLICATION_PREALLOCATED_ARRAY_DEFINITIONS #if defined (ACE_HAS_TSS_EMULATION) // Initialize the main thread's TS storage. @@ -112,16 +169,23 @@ ACE_Object_Manager::~ACE_Object_Manager (void) ACE_TSS_Emulation::tss_close (ts_storage_); #endif /* ACE_HAS_TSS_EMULATION */ +#if ! defined (ACE_HAS_STATIC_PREALLOCATION) + // Hooks for deletion of preallocated objects and arrays provided by + // application. + ACE_APPLICATION_PREALLOCATED_ARRAY_DELETIONS + ACE_APPLICATION_PREALLOCATED_OBJECT_DELETIONS + + // Cleanup the dynamically preallocated objects. # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - // Cleanup the preallocated objects. - for (u_int i = 0; i < ACE_END_OF_PREALLOCATED_OBJECTS - 1; ++i) - { - // The object is an ACE_Managed_Cleanup<ACE_Thread_Mutex). - ace_cleanup_destroyer ( - (ACE_Managed_Cleanup<ACE_Thread_Mutex> *) managed_object[i], 0); - managed_object[i] = 0; - } + ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_LOG_MSG_INSTANCE_LOCK) + ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_MT_CORBA_HANDLER_LOCK) + ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_DUMP_LOCK) + ACE_DELETE_PREALLOCATED_OBJECT (ACE_Thread_Mutex, ACE_TSS_CLEANUP_LOCK) # endif /* ACE_MT_SAFE */ + + // Cleanup the dynamically preallocated arrays. + // (None, yet.) +#endif /* ! ACE_HAS_STATIC_PREALLOCATION */ } ACE_Object_Manager * diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h index 41da52e781c..ef12bb21ccc 100644 --- a/ace/Object_Manager.h +++ b/ace/Object_Manager.h @@ -27,33 +27,98 @@ template <class T> class ACE_Unbounded_Queue; #if !defined (ACE_MAX_MANAGED_OBJECTS) -# define ACE_MAX_MANAGED_OBJECTS 256 -#endif /* ACE_MAX_MANAGED_OBJECTS */ +# define ACE_MAX_MANAGED_OBJECTS 128 +#endif /* ! ACE_MAX_MANAGED_OBJECTS */ + +#if !defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS) +# define ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS +#endif /* ! ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS */ + +#if !defined (ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS) +# define ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS +#endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */ class ACE_Export ACE_Object_Manager // = TITLE // Manager for ACE library services and singleton cleanup. // // = DESCRIPTION - // This class shuts down ACE library services, so that they can - // reclaim their storage, at program termination. It does that by - // creating a static instance, whose destructor gets called along - // with those of all other static objects. Hooks are provided for - // application code to register objects and arrays for - // cleanup, e.g., destruction. Please note that the order of such - // cleanup calls is not specified. Therefore, these cleanup hooks - // should not depend on any of the static instances. Also note that - // ACE_Log_Msg currently takes care of its own cleanup. + // The ACE_Object_Manager manages cleanup of objects, typically + // singletons, at program termination. In addition to managing + // the cleanup of the ACE library, it provides an interface for + // application to register objects to be cleaned up. + // + // This class also shuts down ACE library services, so that they + // can reclaim their storage, at program termination. It works + // by creating a static instance whose destructor gets called + // along with those of all other static objects. Hooks are + // provided for application code to register objects and arrays + // for cleanup, e.g., destruction. The order of such cleanup + // calls is in the reverse order of registration, i.e., that + // last object/array to register gets cleaned up first. + // + // The ACE_Object_Manager API includes ACE_Managed_Object. That + // class is contained in a separate file because it is a + // template class, and some compilers require that template and + // non-template class definitions appear in separate files. + // Please see ace/Managed_Object.h for a description of that + // part of the API. In summary, Managed_Object provides two + // adapters, the ACE_Managed_Cleanup and ACE_Managed_Object + // template classes for adapting objects of any type to be + // easily managed by the ACE_Object_Manager. There are several + // mechanisms for adapting objects and arrays for cleanup at + // program termination, in roughly increasing order of ease-of-use: + // + // 1) Derive the object's class from ACE_Cleanup. + // 2) Allow the ACE_Object_Manager to both dynamically allocate + // and deallocate the object. + // 3) Provide an ACE_CLEANUP_FUNC cleanup hook for the object or + // array. + // 4) Allow the ACE_Object_Manager to both preallocate the object + // or array, either statically in global data or dynamically on + // the heap, when its singleton instance is construction. + // + // There are also several mechanisms for registering objects and + // arrays for cleanup. In decreasing order of flexibility and + // complexity (with the exception of the last mechanism): + // + // 1) ACE_Object_Manager::at_exit (void *object, + // ACE_CLEANUP_FUNC cleanup_hook, + // void *param); + // can be used to register any object or array for any + // cleanup activity at program termination. + // + // 2) ACE_Object_Manager::at_exit (ACE_Cleanup *object, + // void *param = 0); + // can be used to register an ACE_Cleanup object + // for any cleanup activity at program termination. + // + // 3) ACE_Managed_Object::get_object (int &id, TYPE *&object); + // can be used to dynamically allocate an object of any TYPE. + // The object is deleted at program termination. // - // It would be worth adding a capability to do the shutdown prior - // to static object destruction, e.g., via an ::at_exit () call. - // Without that capability, on VxWorks, for example, the program - // must be unloaded for this to work. (On VxWorks, - // alternatively, the explicity OS calls to call all static - // destructors and constructors could be used.) + // The final mechanism is not general purpose, but can only + // be used to allocate objects and arrays at program startup: + // + // 4) ACE_Managed_Object::get_preallocated_object + // (ACE_Object_Manager::Preallocated_Object id); + // and + // ACE_Managed_Object::get_preallocated_array + // (ACE_Object_Manager::Preallocated_Array id); + // can only be used to allocate objects at program startup, + // either in global data or on the heap (selected at compile + // time). These are intended to replace static locks, etc. + // + // Instead of creating a static ACE_Object_Manager instance, one + // can alternatively be created on the stack of the main program + // thread. It is created just after entry to ::main (int, char + // *[]), and before any existing code in that function is + // executed. To enable this alternative, add #define + // ACE_HAS_NONSTATIC_OBJECT_MANAGER to ace/config.h prior to + // building the ACE library and your applications. This #define + // is enabled in the VxWorks config files that are supplied with + // ACE. // - // WARNING: this class is under development. Its interface - // is likely to change, without providing backward capability. { public: static int at_exit (ACE_Cleanup *object, void *param = 0); @@ -92,31 +157,57 @@ public: // when the current thread exits instead of when the program terminates. #endif /* 0 */ - enum Preallocated_Objects + enum Preallocated_Object { - ACE_NULL_PREALLOCATED_OBJECT, - #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) ACE_LOG_MSG_INSTANCE_LOCK, ACE_MT_CORBA_HANDLER_LOCK, ACE_DUMP_LOCK, ACE_TSS_CLEANUP_LOCK, +#else + ACE_NO_PREALLOCATED_OBJECTS, // To avoid an empty array. #endif /* ACE_MT_SAFE */ - ACE_END_OF_PREALLOCATED_OBJECTS // This enum value must be last! + // Hook for preallocated objects provided by application. + ACE_APPLICATION_PREALLOCATED_OBJECT_DECLARATIONS + + ACE_PREALLOCATED_OBJECTS // This enum value must be last! }; + // Unique identifiers for preallocated objects. Please see + // ace/Managed_Object.h for information on accessing preallocated + // objects. -private: - static ACE_Object_Manager *instance_; - // Singleton pointer. + enum Preallocated_Array + { + ACE_FILECACHE_HASH_LOCK, + ACE_FILECACHE_FILE_LOCK, + + // Hook for preallocated arrays provided by application. + ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS + ACE_PREALLOCATED_ARRAYS // This enum value must be last! + }; + // Unique identifiers for preallocated arrays. Please see + // ace/Managed_Object.h for information on accessing preallocated + // arrays. + +private: ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_; // Keeps track of all registered objects. int shutting_down_; // Non-zero if this being destroyed + int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); + // Register an object or array for deletion at program termination. + // See description of static version above for return values. + + static ACE_Object_Manager *instance_; + // Singleton pointer. + public: + // For internal use only by ACE_Managed_Objects. + ACE_MT (ACE_Thread_Mutex *lock_); // Lock that is used to guard internal structures. Just a pointer // is declared here in order to minimize the headers that this one @@ -133,10 +224,11 @@ public: static u_int next_managed_object; // Index of the next available managed object table slot. -private: - int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); - // Register an object or array for deletion at program termination. - // See description of static version above for return values. + static void *preallocated_object[ACE_PREALLOCATED_OBJECTS]; + // Table of preallocated objects. + + static void *preallocated_array[ACE_PREALLOCATED_ARRAYS]; + // Table of preallocated arrays. public: // Application code should not use these explicitly, so they're @@ -145,8 +237,8 @@ public: // ACE_HAS_NONSTATIC_OBJECT_MANAGER. ACE_Object_Manager (void); ~ACE_Object_Manager (void); -private: +private: #if defined (ACE_HAS_TSS_EMULATION) // Main thread's thread-specific storage array. void *ts_storage_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]; |