summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog-99b68
-rw-r--r--ace/OS.cpp142
-rw-r--r--ace/OS.h61
-rw-r--r--ace/OS.i21
-rw-r--r--ace/Object_Manager.cpp99
-rw-r--r--ace/Object_Manager.h6
-rw-r--r--ace/README6
-rw-r--r--tests/Makefile3
-rw-r--r--tests/Object_Manager_Test.cpp108
-rw-r--r--tests/icc.bat3
-rwxr-xr-xtests/run_pharlap_tests.bat1
-rw-r--r--tests/run_tests.bat1
-rw-r--r--tests/run_tests.lst1
-rwxr-xr-xtests/run_tests.psosim2
-rw-r--r--tests/run_tests.vxworks4
-rw-r--r--tests/t.icc4
16 files changed, 385 insertions, 145 deletions
diff --git a/ChangeLog-99b b/ChangeLog-99b
index aed0779850b..dc233ed2c77 100644
--- a/ChangeLog-99b
+++ b/ChangeLog-99b
@@ -1,50 +1,62 @@
+Tue Aug 24 07:11:52 1999 David L. Levine <levine@cs.wustl.edu>
+
+ * ace/OS.*,Object_Manager.{h,cpp},README: with ACE_LACKS_ATEXIT,
+ use ACE_OS_Object_Manager::at_exit () to emulate atexit ().
+ [Bug 246]
+
+ * tests/Object_Manager_Test.cpp,tests/Makefile,
+ tests/run_pharlap_tests.bat,tests/run_tests.bat,
+ tests/run_tests.lst,tests/run_tests.psosim,
+ tests/run_tests.vxworks,tests/t.icc,tests/icc.bat:
+ added Object_Manager_Test.
+
Mon Aug 23 22:03:24 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
- * include/makeinclude/rules.lib.GNU:
- * include/makeinclude/rules.local.GNU:
- When compiling both shared and static libraries only one of them
- was installed. Thanks to Paul Calabrese <calabrese_p@ociweb.com>
- for providing this fix.
+ * include/makeinclude/rules.lib.GNU:
+ * include/makeinclude/rules.local.GNU:
+ When compiling both shared and static libraries only one of them
+ was installed. Thanks to Paul Calabrese <calabrese_p@ociweb.com>
+ for providing this fix.
Mon Aug 23 21:41:43 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
- * tests/run_tests.pl:
- We search for "Starting" instead of "starting" because that's
- what the tests print out now.
+ * tests/run_tests.pl:
+ We search for "Starting" instead of "starting" because that's
+ what the tests print out now.
Mon Aug 23 21:20:28 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
- * docs/ACE-guidelines.html:
- Added new guidelines relevant to ACE+TAO.
+ * docs/ACE-guidelines.html:
+ Added new guidelines relevant to ACE+TAO.
Mon Aug 23 16:57:13 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
- * performance-tests/RPC/README:
- * performance-tests/RPC/client.cpp:
- Changed the options to make it more consistent with other tests
- like this one.
- Added a README file
+ * performance-tests/RPC/README:
+ * performance-tests/RPC/client.cpp:
+ Changed the options to make it more consistent with other tests
+ like this one.
+ Added a README file
Mon Aug 23 16:53:00 1999 Carlos O'Ryan <coryan@cs.wustl.edu>
- * performance-tests/Makefile:
- * performance-tests/TCP/README:
- Added a README file for the test
+ * performance-tests/Makefile:
+ * performance-tests/TCP/README:
+ Added a README file for the test
- * performance-tests/TCP/tcp_test.cpp:
- Added options to pace the events and to control the message size
- on the server side.
+ * performance-tests/TCP/tcp_test.cpp:
+ Added options to pace the events and to control the message size
+ on the server side.
- * performance-tests/RPC/Makefile:
- * performance-tests/RPC/client.cpp:
- * performance-tests/RPC/ping.x:
- * performance-tests/RPC/server.c:
- Added a simple RPC test to compare sockets (ACE), RPC and TAO.
+ * performance-tests/RPC/Makefile:
+ * performance-tests/RPC/client.cpp:
+ * performance-tests/RPC/ping.x:
+ * performance-tests/RPC/server.c:
+ Added a simple RPC test to compare sockets (ACE), RPC and TAO.
Mon Aug 23 13:30:32 1999 Nanbor Wang <nanbor@cs.wustl.edu>
- * include/makeinclude/platform_sunos5_kcc.GNU: The optimization
- flag for KCC should be +K3, not -K2.
+ * include/makeinclude/platform_sunos5_kcc.GNU: The optimization
+ flag for KCC should be +K3, not -K2.
Mon Aug 23 10:56:40 1999 David L. Levine <levine@cs.wustl.edu>
diff --git a/ace/OS.cpp b/ace/OS.cpp
index 752b7948323..b761cc074d9 100644
--- a/ace/OS.cpp
+++ b/ace/OS.cpp
@@ -291,6 +291,133 @@ ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const
return !(*this == o);
}
+class ACE_Cleanup_Info_Node
+{
+ // = TITLE
+ // For maintaining a list of ACE_Cleanup_Info items.
+ //
+ // = DESCRIPTION
+ // For internal use by ACE_Object_Manager.
+public:
+ ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next);
+ ~ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &);
+private:
+ ACE_Cleanup_Info cleanup_info_;
+ ACE_Cleanup_Info_Node *next_;
+
+ friend class ACE_OS_Exit_Info;
+};
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void)
+ : cleanup_info_ (),
+ next_ (0)
+{
+}
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next)
+ : cleanup_info_ (new_info),
+ next_ (next)
+{
+}
+
+ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void)
+{
+ delete next_;
+}
+
+ACE_Cleanup_Info_Node *
+ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info)
+{
+ ACE_Cleanup_Info_Node *new_node;
+
+ ACE_NEW_RETURN (new_node,
+ ACE_Cleanup_Info_Node (new_info, this),
+ 0);
+
+ return new_node;
+}
+
+ACE_OS_Exit_Info::ACE_OS_Exit_Info (void)
+{
+ ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node);
+}
+
+ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void)
+{
+ delete registered_objects_;
+ registered_objects_ = 0;
+}
+
+int
+ACE_OS_Exit_Info::at_exit_i (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param)
+{
+ ACE_Cleanup_Info new_info;
+ new_info.object_ = object;
+ new_info.cleanup_hook_ = cleanup_hook;
+ new_info.param_ = param;
+
+ // Return -1 and sets errno if unable to allocate storage. Enqueue
+ // at the head and dequeue from the head to get LIFO ordering.
+
+ ACE_Cleanup_Info_Node *new_node;
+
+ if ((new_node = registered_objects_->insert (new_info)) == 0)
+ return -1;
+ else
+ {
+ registered_objects_ = new_node;
+ return 0;
+ }
+}
+
+int
+ACE_OS_Exit_Info::find (void *object)
+{
+ // Check for already in queue, and return 1 if so.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ if (iter->cleanup_info_.object_ == object)
+ {
+ // The object has already been registered.
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+ACE_OS_Exit_Info::call_hooks ()
+{
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ ACE_Cleanup_Info &info = iter->cleanup_info_;
+ if (info.cleanup_hook_ == ACE_reinterpret_cast (ACE_CLEANUP_FUNC,
+ ace_cleanup_destroyer))
+ // The object is an ACE_Cleanup.
+ ace_cleanup_destroyer (ACE_reinterpret_cast (ACE_Cleanup *,
+ info.object_),
+ info.param_);
+ else if (info.object_ == &ace_exit_hook_marker)
+ // The hook is an ACE_EXIT_HOOK.
+ (* ACE_reinterpret_cast (ACE_EXIT_HOOK, info.cleanup_hook_)) ();
+ else
+ (*info.cleanup_hook_) (info.object_, info.param_);
+ }
+}
+
void
ACE_Time_Value::dump (void) const
{
@@ -6299,6 +6426,7 @@ void *ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS] = { 0 };
ACE_OS_Object_Manager::ACE_OS_Object_Manager ()
+ : exit_info_ ()
{
// If instance_ was not 0, then another ACE_OS_Object_Manager has
// already been instantiated (it is likely to be one initialized by way
@@ -6454,6 +6582,10 @@ ACE_OS_Object_Manager::fini (void)
next_ = 0; // Protect against recursive calls.
}
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ exit_info_.call_hooks ();
+
// Only clean up preallocated objects when the singleton Instance is being
// destroyed.
if (this == instance_)
@@ -6545,6 +6677,16 @@ ACE_OS_Object_Manager::fini (void)
return 0;
}
+int ace_exit_hook_marker = 0;
+
+int
+ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func)
+{
+ return exit_info_.at_exit_i (&ace_exit_hook_marker,
+ ACE_reinterpret_cast (ACE_CLEANUP_FUNC, func),
+ 0);
+}
+
int
ACE_OS_Object_Manager::starting_up (void)
{
diff --git a/ace/OS.h b/ace/OS.h
index d7fac310ed6..cea05e4c9ba 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -4601,6 +4601,9 @@ typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */;
}
# endif /* ACE_HAS_SIG_C_FUNC */
+// Marker for cleanup, used by ACE_Exit_Info.
+extern int ace_exit_hook_marker;
+
// For use by <ACE_OS::exit>.
extern "C"
{
@@ -4656,6 +4659,40 @@ public:
// Parameter passed to the <cleanup_hook_>.
};
+class ACE_Cleanup_Info_Node;
+
+class ACE_OS_Exit_Info
+{
+ // = TITLE
+ // Hold Object Manager cleanup (exit) information.
+ //
+ // = DESCRIPTION
+ // For internal use by the ACE library, only.
+public:
+ ACE_OS_Exit_Info (void);
+ // Default constructor.
+
+ ~ACE_OS_Exit_Info (void);
+ // Destructor.
+
+ int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);
+ // Use to register a cleanup hook.
+
+ int find (void *object);
+ // Look for a registered cleanup hook object. Returns 1 if already
+ // registered, 0 if not.
+
+ void call_hooks ();
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+
+private:
+ ACE_Cleanup_Info_Node *registered_objects_;
+ // Keeps track of all registered objects. The last node is only
+ // used to terminate the list (it doesn't contain a valid
+ // ACE_Cleanup_Info).
+};
+
// Run the thread entry point for the <ACE_Thread_Adapter>. This must
// be an extern "C" to make certain compilers happy...
extern "C" ACE_Export void *ace_thread_adapter (void *args);
@@ -6801,15 +6838,6 @@ public:
// Destructor.
private:
- friend class ACE_OS;
- friend class ACE_Object_Manager;
- friend class ACE_OS_Object_Manager_Manager;
- friend class ACE_TSS_Cleanup;
- friend class ACE_TSS_Emulation;
- friend class ACE_Log_Msg;
- friend void ACE_OS_Object_Manager_Internal_Exit_Hook ();
- // This class is for internal use by ACE_OS, etc., only.
-
static ACE_OS_Object_Manager *instance (void);
// Accessor to singleton instance.
@@ -6818,6 +6846,21 @@ private:
static void *preallocated_object[ACE_OS_PREALLOCATED_OBJECTS];
// Table of preallocated objects.
+
+ ACE_OS_Exit_Info exit_info_;
+ // For at_exit support.
+
+ int at_exit (ACE_EXIT_HOOK func);
+ // For ACE_OS::atexit () support, with ACE_LACKS_ATEXIT.
+
+ friend class ACE_OS;
+ friend class ACE_Object_Manager;
+ friend class ACE_OS_Object_Manager_Manager;
+ friend class ACE_TSS_Cleanup;
+ friend class ACE_TSS_Emulation;
+ friend class ACE_Log_Msg;
+ friend void ACE_OS_Object_Manager_Internal_Exit_Hook ();
+ // This class is for internal use by ACE_OS, etc., only.
};
# if defined (ACE_HAS_WINCE)
diff --git a/ace/OS.i b/ace/OS.i
index f9e5e2b1c6d..d921b985241 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -1185,8 +1185,7 @@ ACE_INLINE int
ACE_OS::atexit (ACE_EXIT_HOOK func)
{
#if defined (ACE_LACKS_ATEXIT)
- ACE_UNUSED_ARG (func);
- ACE_NOTSUP_RETURN (-1);
+ return ACE_OS_Object_Manager::instance ()->at_exit (func);
#else
return ::atexit (func);
#endif /* ACE_LACKS_ATEXIT */
@@ -4889,7 +4888,7 @@ ACE_OS::join_leaf (ACE_HANDLE socket,
FLOWSPEC sending_flowspec;
FLOWSPEC receiving_flowspec;
-
+
// Construct the sending Flowspec.
sending_flowspec.TokenRate = qos_params.socket_qos ()->sending_flowspec ().token_rate ();
@@ -4900,10 +4899,10 @@ ACE_OS::join_leaf (ACE_HANDLE socket,
sending_flowspec.ServiceType = qos_params.socket_qos ()->sending_flowspec ().service_type ();
sending_flowspec.MaxSduSize = qos_params.socket_qos ()->sending_flowspec ().max_sdu_size ();
sending_flowspec.MinimumPolicedSize = qos_params.socket_qos ()->sending_flowspec ().minimum_policed_size ();
-
-
+
+
// Construct the receiving Flowspec.
-
+
receiving_flowspec.TokenRate = qos_params.socket_qos ()->receiving_flowspec ().token_rate ();
receiving_flowspec.TokenBucketSize = qos_params.socket_qos ()->receiving_flowspec ().token_bucket_size ();
receiving_flowspec.PeakBandwidth = qos_params.socket_qos ()->receiving_flowspec ().peak_bandwidth ();
@@ -4912,14 +4911,14 @@ ACE_OS::join_leaf (ACE_HANDLE socket,
receiving_flowspec.ServiceType = qos_params.socket_qos ()->receiving_flowspec ().service_type ();
receiving_flowspec.MaxSduSize = qos_params.socket_qos ()->receiving_flowspec ().max_sdu_size ();
receiving_flowspec.MinimumPolicedSize = qos_params.socket_qos ()->receiving_flowspec ().minimum_policed_size ();
-
-
+
+
// Construct the WinSock2 QOS structure.
-
+
qos.SendingFlowspec = sending_flowspec;
qos.ReceivingFlowspec = receiving_flowspec;
qos.ProviderSpecific = (WSABUF) qos_params.socket_qos ()->provider_specific ();
-
+
ACE_SOCKCALL_RETURN (::WSAJoinLeaf ((ACE_SOCKET) socket,
name,
namelen,
@@ -4930,7 +4929,7 @@ ACE_OS::join_leaf (ACE_HANDLE socket,
qos_params.flags ()),
ACE_HANDLE,
ACE_INVALID_HANDLE);
-
+
#else
ACE_UNUSED_ARG (socket);
ACE_UNUSED_ARG (name);
diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp
index 58aa8d754a7..0c1136245c3 100644
--- a/ace/Object_Manager.cpp
+++ b/ace/Object_Manager.cpp
@@ -154,26 +154,6 @@ ACE_Object_Manager_Preallocations::~ACE_Object_Manager_Preallocations (void)
{
}
-class ACE_Cleanup_Info_Node
-{
- // = TITLE
- // For maintaining a list of ACE_Cleanup_Info items.
- //
- // = DESCRIPTION
- // For internal use by ACE_Object_Manager.
-public:
- ACE_Cleanup_Info_Node (void);
- ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
- ACE_Cleanup_Info_Node *next);
- ~ACE_Cleanup_Info_Node (void);
- ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &);
-private:
- ACE_Cleanup_Info cleanup_info_;
- ACE_Cleanup_Info_Node *next_;
-
- friend class ACE_Object_Manager;
-};
-
int
ACE_Object_Manager::starting_up (void)
{
@@ -240,13 +220,6 @@ ACE_Object_Manager::init (void)
# endif /* ACE_MT_SAFE */
}
- // Do this after the allocation of ACE_STATIC_OBJECT_LOCK. It
- // shouldn't matter, but just in case
- // ACE_Static_Object_Lock::instance () gets changed . . .
- ACE_NEW_RETURN (registered_objects_,
- ACE_Cleanup_Info_Node,
- -1);
-
if (this == instance_)
{
// Hooks for preallocated objects and arrays provided by application.
@@ -282,7 +255,7 @@ ACE_Object_Manager::init (void)
ACE_Object_Manager::ACE_Object_Manager (void)
// With ACE_HAS_TSS_EMULATION, ts_storage_ is initialized by the call to
// ACE_OS::tss_open () in the function body.
- : registered_objects_ (0)
+ : exit_info_ ()
, preallocations_ (0)
, default_mask_ (0)
, ace_service_config_sig_handler_ (0)
@@ -358,28 +331,14 @@ ACE_Object_Manager::at_exit_i (void *object,
return -1;
}
- // Check for already in queue, and return 1 if so.
- for (ACE_Cleanup_Info_Node *iter = registered_objects_;
- iter && iter->next_ != 0;
- iter = iter->next_)
+ if (exit_info_.find (object))
{
- if (iter->cleanup_info_.object_ == object)
- {
- // The object has already been registered.
- errno = EEXIST;
- return -1;
- }
+ // The object has already been registered.
+ errno = EEXIST;
+ return -1;
}
- ACE_Cleanup_Info new_info;
- new_info.object_ = object;
- new_info.cleanup_hook_ = cleanup_hook;
- new_info.param_ = param;
-
- // Return -1 and sets errno if unable to allocate storage. Enqueue
- // at the head and dequeue from the head to get LIFO ordering.
- registered_objects_ = registered_objects_->insert (new_info);
- return registered_objects_ == 0 ? -1 : 0;
+ return exit_info_.at_exit_i (object, cleanup_hook, param);
}
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
@@ -626,17 +585,7 @@ ACE_Object_Manager::fini (void)
// Call all registered cleanup hooks, in reverse order of
// registration.
- for (ACE_Cleanup_Info_Node *iter = registered_objects_;
- iter && iter->next_ != 0;
- iter = iter->next_)
- {
- ACE_Cleanup_Info &info = iter->cleanup_info_;
- if (info.cleanup_hook_ == (ACE_CLEANUP_FUNC) ace_cleanup_destroyer)
- // The object is an ACE_Cleanup.
- ace_cleanup_destroyer ((ACE_Cleanup *) info.object_, info.param_);
- else
- (*info.cleanup_hook_) (info.object_, info.param_);
- }
+ exit_info_.call_hooks ();
if (this == instance_)
{
@@ -711,9 +660,6 @@ ACE_Object_Manager::fini (void)
delete ace_service_config_sig_handler_;
ace_service_config_sig_handler_ = 0;
- delete registered_objects_;
- registered_objects_ = 0;
-
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
delete internal_lock_;
internal_lock_ = 0;
@@ -744,37 +690,6 @@ ACE_Object_Manager::fini (void)
}
-ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void)
- : cleanup_info_ (),
- next_ (0)
-{
-}
-
-ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
- ACE_Cleanup_Info_Node *next)
- : cleanup_info_ (new_info),
- next_ (next)
-{
-}
-
-ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void)
-{
- delete next_;
-}
-
-ACE_Cleanup_Info_Node *
-ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info)
-{
- ACE_Cleanup_Info_Node *new_node;
-
- ACE_NEW_RETURN (new_node,
- ACE_Cleanup_Info_Node (new_info, this),
- 0);
-
- return new_node;
-}
-
-
#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
class ACE_Export ACE_Object_Manager_Manager
// = TITLE
diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h
index 0de0f782645..65b7db06fce 100644
--- a/ace/Object_Manager.h
+++ b/ace/Object_Manager.h
@@ -294,10 +294,8 @@ public:
// Accesses a default signal set used in ACE_Sig_Guard methods.
private:
- ACE_Cleanup_Info_Node *registered_objects_;
- // Keeps track of all registered objects. The last node is only
- // used to terminate the list (it doesn't contain a valid
- // ACE_Cleanup_Info).
+ ACE_OS_Exit_Info exit_info_;
+ // For at_exit support.
ACE_Object_Manager_Preallocations *preallocations_;
// Preallocated objects collection.
diff --git a/ace/README b/ace/README
index 3cb33367089..7ca5b88be03 100644
--- a/ace/README
+++ b/ace/README
@@ -634,6 +634,12 @@ ACE_LACKS_ACE_IOSTREAM Platform can not build
the platform does not support
iostreams.
ACE_LACKS_ATEXIT Platform does not support ::atexit ().
+ Use ACE's at_exit () emulation instead.
+ NOTE: should be used with
+ ACE_HAS_NONSTATIC_OBJECT_MANAGER for
+ proper semantics of _when_ exit hooks
+ are destroyed, i.e., prior to static
+ object destruction.
ACE_LACKS_AUTO_MMAP_REPLACEMENT No system support for replacing any
previous mappings.
ACE_LACKS_BSEARCH Compiler/platform lacks the
diff --git a/tests/Makefile b/tests/Makefile
index 1d5cce11073..e66c9c5c9f1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -44,13 +44,14 @@ BIN = Aio_Platform_Test \
Message_Queue_Notifications_Test \
New_Fail_Test \
Notify_Performance_Test \
+ Object_Manager_Test \
Process_Mutex_Test \
Process_Strategy_Test \
Priority_Buffer_Test \
Dynamic_Priority_Test \
Priority_Task_Test \
Priority_Reactor_Test \
- Process_Manager_Test \
+ Process_Manager_Test \
Pipe_Test \
RB_Tree_Test \
Reactors_Test \
diff --git a/tests/Object_Manager_Test.cpp b/tests/Object_Manager_Test.cpp
new file mode 100644
index 00000000000..8a4b8e1fb2c
--- /dev/null
+++ b/tests/Object_Manager_Test.cpp
@@ -0,0 +1,108 @@
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// tests
+//
+// = FILENAME
+// Object_Manager_Test.cpp
+//
+// = DESCRIPTION
+// Tests the basic functions of the ACE_Object_Manager.
+//
+// = AUTHOR
+// David L. Levine
+//
+// ============================================================================
+
+#include "test_config.h"
+#include "ace/Object_Manager.h"
+
+static u_int *ip;
+
+extern "C"
+void
+hook1 (void)
+{
+ delete ip;
+ ip = 0;
+}
+
+extern "C"
+void
+hook2 (void * /* object */, void *param)
+{
+ u_int *paramp = ACE_reinterpret_cast (u_int *, param);
+
+ // We can use ACE_Log_Msg in an ACE_Object_Manager cleanup hook.
+ // But NOT in an ACE_OS::atexit () hook! However, the ACE_END_TEST
+ // invocation in main () will prevent this from being output to the
+ // log stream.
+ ACE_DEBUG ((LM_DEBUG, "hook2: %d\n", *paramp));
+
+ delete paramp;
+}
+
+int
+main (int, ASYS_TCHAR *[])
+{
+ ACE::init ();
+
+ ACE_START_TEST (ASYS_TEXT ("Object_Manager_Test"));
+
+ u_int errors = 0;
+
+ // If hook1 never gets called, this will show up as a memory leak.
+ ACE_NEW_RETURN (ip, u_int, -1);
+
+ const int starting_up = ACE_Object_Manager::instance ()->starting_up ();
+ const int shutting_down = ACE_Object_Manager::instance ()->shutting_down ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ASYS_TEXT ("starting_up: %d, shutting_down: %d\n"),
+ starting_up,
+ shutting_down));
+
+ if (starting_up || shutting_down)
+ {
+ ++errors;
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("starting_up and shutting_down are supposed to ")
+ ASYS_TEXT (" be 0!!!!")));
+ }
+
+ if (ACE_OS::atexit (hook1))
+ {
+ ++errors;
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("ACE_OS::atexit () returned non-zero!!!!")));
+ }
+
+ for (u_int i = 0; i < 10; ++i)
+ {
+ u_int *paramp;
+ ACE_NEW_RETURN (paramp, u_int, -1);
+ *paramp = i;
+
+ // The first paramp argument is only used to distinguish the
+ // at_exit entries. The ACE_Object_Manager only allows one
+ // at_exit per object. It's not used in the hook.
+ if (ACE_Object_Manager::instance ()->at_exit (paramp, hook2, paramp))
+ {
+ ++errors;
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("ACE_Object_Manager::at_exit () ")
+ ASYS_TEXT ("returned non-zero!!!!")));
+ }
+ }
+
+ ACE_END_TEST;
+
+ ACE::fini ();
+
+ return errors == 0 ? 0 : 1;
+}
diff --git a/tests/icc.bat b/tests/icc.bat
index a54461b85ea..a34ad0f5b97 100644
--- a/tests/icc.bat
+++ b/tests/icc.bat
@@ -28,6 +28,7 @@ vacbld -SEV=E Message_Queue_Notifications_Test.icc
vacbld -SEV=E Message_Queue_Test.icc
vacbld -SEV=E Naming_Test.icc
vacbld -SEV=E Notify_Performance_Test.icc
+vacbld -SEV=E Object_Manager_Test.icc
vacbld -SEV=E OrdMultiSet_Test.icc
vacbld -SEV=E Pipe_Test.icc
vacbld -SEV=E Priority_Buffer_Test.icc
@@ -105,6 +106,7 @@ vacbld -SEV=E Message_Queue_Notifications_Test.icc
vacbld -SEV=E Message_Queue_Test.icc
vacbld -SEV=E Naming_Test.icc
vacbld -SEV=E Notify_Performance_Test.icc
+vacbld -SEV=E Object_Manager_Test.icc
vacbld -SEV=E OrdMultiSet_Test.icc
vacbld -SEV=E Pipe_Test.icc
vacbld -SEV=E Priority_Buffer_Test.icc
@@ -182,6 +184,7 @@ vacbld -SEV=E Message_Queue_Notifications_Test.icc
vacbld -SEV=E Message_Queue_Test.icc
vacbld -SEV=E Naming_Test.icc
vacbld -SEV=E Notify_Performance_Test.icc
+vacbld -SEV=E Object_Manager_Test.icc
vacbld -SEV=E OrdMultiSet_Test.icc
vacbld -SEV=E Pipe_Test.icc
vacbld -SEV=E Priority_Buffer_Test.icc
diff --git a/tests/run_pharlap_tests.bat b/tests/run_pharlap_tests.bat
index 9f6da7b1293..88e6ee8b575 100755
--- a/tests/run_pharlap_tests.bat
+++ b/tests/run_pharlap_tests.bat
@@ -47,6 +47,7 @@ call %0 MT_SOCK_Test
call %0 Naming_Test
call %0 New_Fail_Test
call %0 Notify_Performance_Test
+call %0 Object_Manager_Test
call %0 OrdMultiSet_Test
call %0 Pipe_Test
call %0 Priority_Buffer_Test
diff --git a/tests/run_tests.bat b/tests/run_tests.bat
index 7456f1c458f..e3bbaf467a4 100644
--- a/tests/run_tests.bat
+++ b/tests/run_tests.bat
@@ -97,6 +97,7 @@ call %run_cmd% %dopure% %platform% Malloc_Test
call %run_cmd% %dopure% %platform% Naming_Test
rem call %run_cmd% %dopure% %platform% New_Fail_Test
call %run_cmd% %dopure% %platform% Notify_Performance_Test
+call %run_cmd% %dopure% %platform% Object_Manager_Test
call %run_cmd% %dopure% %platform% OrdMultiSet_Test
call %run_cmd% %dopure% %platform% Pipe_Test
call %run_cmd% %dopure% %platform% Priority_Buffer_Test
diff --git a/tests/run_tests.lst b/tests/run_tests.lst
index d2bfa56db5e..ed9135d323d 100644
--- a/tests/run_tests.lst
+++ b/tests/run_tests.lst
@@ -1,6 +1,7 @@
Basic_Types_Test
chorus/Env_Value_Test
Atomic_Op_Test
+Object_Manager_Test
CDR_Test
Semaphore_Test
TSS_Test
diff --git a/tests/run_tests.psosim b/tests/run_tests.psosim
index a788025b628..dd274a9e239 100755
--- a/tests/run_tests.psosim
+++ b/tests/run_tests.psosim
@@ -39,6 +39,8 @@ run DLList_Test
#Atomic_Op_Test: threads not supported on this platform
#run Atomic_Op_Test # uses Atomic_Op
+run Object_Manager_Test
+
#TSS_Test: threads are not supported on this platform
#run TSS_Test # uses Task, Mutex, Guard
diff --git a/tests/run_tests.vxworks b/tests/run_tests.vxworks
index cbf03135b23..095932190f7 100644
--- a/tests/run_tests.vxworks
+++ b/tests/run_tests.vxworks
@@ -60,6 +60,10 @@ ld < Atomic_Op_Test
write 2, "Atomic_Op_Test ", 15
ace_main; unld "Atomic_Op_Test"
+ld < Object_Manager_Test
+write 2, "Object_Manager_Test ", 20
+ace_main; unld "Object_Manager_Test"
+
ld < Semaphore_Test
write 2, "Semaphore_Test ", 15
ace_main; unld "Semaphore_Test"
diff --git a/tests/t.icc b/tests/t.icc
index bdd9992b852..45d5f107779 100644
--- a/tests/t.icc
+++ b/tests/t.icc
@@ -119,6 +119,10 @@ option
{
source type(cpp) "Notify_Performance_Test.cpp"
}
+ target "Object_Manager_Test.exe"
+ {
+ source type(cpp) "Object_Manager_Test.cpp"
+ }
target "OrdMultiSet_Test.exe"
{
source type(cpp) "OrdMultiSet_Test.cpp"