diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-09 16:36:29 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-09-09 16:36:29 +0000 |
commit | b0e472945fe902d291a531902c218300b54e1717 (patch) | |
tree | 705895e29c7be9ad0982fdfdcc7df9ae4fe6a543 /ace/Object_Manager.cpp | |
parent | 87cdc5c3783a1da02b29637583950754246162d0 (diff) | |
download | ATCD-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.cpp | 122 |
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> |