summaryrefslogtreecommitdiff
path: root/ace/Object_Manager.cpp
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-09 16:36:29 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-09 16:36:29 +0000
commitb0e472945fe902d291a531902c218300b54e1717 (patch)
tree705895e29c7be9ad0982fdfdcc7df9ae4fe6a543 /ace/Object_Manager.cpp
parent87cdc5c3783a1da02b29637583950754246162d0 (diff)
downloadATCD-b0e472945fe902d291a531902c218300b54e1717.tar.gz
added guard of internal structures. (dtor): call at_exit hooks before calling cleanup_tss, now that the ACE_TSS_Cleanup instance is no longer registered for an at_exit call. (at_exit): set errno instead of returning different values on error. Added ACE_Managed_Object template class, intended for use in replacing static instances.
Diffstat (limited to 'ace/Object_Manager.cpp')
-rw-r--r--ace/Object_Manager.cpp122
1 files changed, 110 insertions, 12 deletions
diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp
index 53dd00bdf30..3fd2e4a28cc 100644
--- a/ace/Object_Manager.cpp
+++ b/ace/Object_Manager.cpp
@@ -6,6 +6,7 @@
#include "ace/Containers.h"
#include "ace/Service_Repository.h"
#include "ace/Log_Msg.h"
+#include "ace/Synch.h"
#if !defined (__ACE_INLINE__)
#include "ace/Object_Manager.i"
@@ -19,6 +20,8 @@ ACE_Object_Manager::ACE_Object_Manager (void)
{
ACE_NEW (registered_objects_, ACE_Unbounded_Queue<ACE_Cleanup_Info>);
+ ACE_MT (ACE_NEW (lock_, ACE_Thread_Mutex));
+
#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
// Store the address of this static instance so that instance ()
// doesn't allocate a new one when called.
@@ -33,15 +36,13 @@ ACE_Object_Manager::ACE_Object_Manager (void)
ACE_Object_Manager::~ACE_Object_Manager (void)
{
- ACE_Cleanup_Info info;
-
- // This call closes and deletes all ACE library services and
- // singletons. This closes the ACE_Thread_Manager, which cleans
- // up all running threads.
- ACE_Service_Config::close ();
+ // Acquire the mutex here. This should be called from the main
+ // thread. Any other threads that attempt to acquire the mutex will
+ // block. They should be killed when the Thread_Manager is
+ // destroyed, below; so they should never proceed beyond that.
+ ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, *lock_));
- // Close the main thread's TSS, including its Log_Msg instance.
- ACE_OS::cleanup_tss ();
+ ACE_Cleanup_Info info;
// Call all registered cleanup hooks, in reverse order of
// registration. Before starting, mark this object as being
@@ -63,6 +64,16 @@ ACE_Object_Manager::~ACE_Object_Manager (void)
}
}
+ // This call closes and deletes all ACE library services and
+ // singletons. This closes the ACE_Thread_Manager, which cleans
+ // up all running threads.
+ ACE_Service_Config::close ();
+
+ // Close the main thread's TSS, including its Log_Msg instance.
+ ACE_OS::cleanup_tss ();
+
+ ACE_MT (delete lock_; lock_ = 0);
+
delete registered_objects_;
registered_objects_ = 0;
@@ -97,8 +108,13 @@ ACE_Object_Manager::at_exit_i (void *object,
ACE_CLEANUP_FUNC cleanup_hook,
void *param)
{
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock_, -1));
+
if (shutting_down_)
- return -1;
+ {
+ errno = EAGAIN;
+ return -1;
+ }
// Check for already in queue, and return 1 if so.
ACE_Cleanup_Info *info = 0;
@@ -109,7 +125,8 @@ ACE_Object_Manager::at_exit_i (void *object,
if (info->object_ == object)
{
// The object has already been registered.
- return 1;
+ errno = EEXIST;
+ return -1;
}
}
@@ -118,16 +135,97 @@ ACE_Object_Manager::at_exit_i (void *object,
new_info.cleanup_hook_ = cleanup_hook;
new_info.param_ = param;
- // Returns -1 if unable to allocate storage. Enqueue at the head
- // and dequeue from the head to get LIFO ordering.
+ // Returns -1 and sets errno if unable to allocate storage. Enqueue
+ // at the head and dequeue from the head to get LIFO ordering.
return registered_objects_->enqueue_head (new_info);
}
+void *ACE_Object_Manager::managed_object[ACE_MAX_MANAGED_OBJECTS] = { 0 };
+
+u_int ACE_Object_Manager::next_managed_object = 0;
+
+template <class TYPE>
+int
+ACE_Managed_Object<TYPE>::get_object (u_int &id, TYPE *&object)
+{
+ // 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, -1));
+
+ if (id == 0)
+ {
+ // User is requesting a new object.
+ if (ACE_Object_Manager::next_managed_object < ACE_MAX_MANAGED_OBJECTS)
+ {
+ // Allocate a new object, store it in the table, and return it.
+ ACE_NEW_RETURN (object, TYPE, -1);
+ if (object == 0)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ else
+ {
+ ACE_Object_Manager::managed_object[
+ ACE_Object_Manager::next_managed_object++] = object;
+ return 0;
+ }
+ }
+ else
+ {
+ // No more managed_object table slots.
+ object = 0;
+ errno = ENOSPC;
+ return -1;
+ }
+ }
+ else if (id >= ACE_Object_Manager::next_managed_object)
+ {
+ // Unknown, non-zero id.
+ object = 0;
+ errno = ENOENT;
+ return -1;
+ }
+ else
+ {
+ // id is known, so return the object. Cast its type based
+ // on the type of the function template parameter.
+ object = (TYPE *) ACE_Object_Manager::managed_object[id];
+ return 0;
+ }
+}
+
+template <class TYPE>
+TYPE *
+ACE_Managed_Object<TYPE>::get_object (u_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 || id >= ACE_Object_Manager::next_managed_object)
+ {
+ return 0;
+ }
+ else
+ {
+ // id is known, so return the object. Cast its type based
+ // on the type of the function template parameter.
+ return (TYPE *) ACE_Object_Manager::managed_object[id];
+ }
+}
+
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ template class ACE_Managed_Object <ACE_Thread_Mutex>;
+# endif /* ACE_MT_SAFE */
template class ACE_Unbounded_Queue<ACE_Cleanup_Info>;
template class ACE_Unbounded_Queue_Iterator<ACE_Cleanup_Info>;
template class ACE_Node<ACE_Cleanup_Info>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# pragma instantiate ACE_Managed_Object <ACE_Thread_Mutex>
+# endif /* ACE_MT_SAFE */
#pragma instantiate ACE_Unbounded_Queue<ACE_Cleanup_Info>
#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Cleanup_Info>
#pragma instantiate ACE_Node<ACE_Cleanup_Info>