summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-20 22:32:07 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-20 22:32:07 +0000
commit5ee93a4dba1542ad8d2136ba0ffb389bbefc16b0 (patch)
treedfedd325947bec8380259bf875c36a9f61a4a574
parent7ed16425b8bed4d147fa7eb2ad8434de100fbc5a (diff)
downloadATCD-5ee93a4dba1542ad8d2136ba0ffb389bbefc16b0.tar.gz
revised ACE_Object_Manager interface for preallocated objects
-rw-r--r--ace/CORBA_Handler.cpp62
-rw-r--r--ace/CORBA_Handler.h21
-rw-r--r--ace/Dump.cpp13
-rw-r--r--ace/Dump.h5
-rw-r--r--ace/Log_Msg.cpp6
-rw-r--r--ace/Managed_Object.cpp42
-rw-r--r--ace/Managed_Object.h60
-rw-r--r--ace/Managed_Object.i52
-rw-r--r--ace/OS.cpp56
-rw-r--r--ace/Object_Manager.cpp104
-rw-r--r--ace/Object_Manager.h154
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];