diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-09-03 00:19:05 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-09-03 00:19:05 +0000 |
commit | 341cbc7c3a474f1b1350076b14c2d60652728a47 (patch) | |
tree | bbc69e58be4b9f20d77bce8e4be665b515abdfd8 | |
parent | b917f7cb29895c47c3042ca6fa352ab88d837d83 (diff) | |
download | ATCD-341cbc7c3a474f1b1350076b14c2d60652728a47.tar.gz |
*** empty log message ***
-rw-r--r-- | ChangeLog-97b | 16 | ||||
-rw-r--r-- | ace/OS.h | 14 | ||||
-rw-r--r-- | ace/Object_Manager.cpp | 22 | ||||
-rw-r--r-- | ace/Object_Manager.h | 22 | ||||
-rw-r--r-- | ace/Task.cpp | 14 | ||||
-rw-r--r-- | ace/Task.h | 4 | ||||
-rw-r--r-- | ace/Thread_Manager.cpp | 56 | ||||
-rw-r--r-- | ace/Thread_Manager.h | 35 |
8 files changed, 142 insertions, 41 deletions
diff --git a/ChangeLog-97b b/ChangeLog-97b index f40f8b6fd5c..b6d28976ff1 100644 --- a/ChangeLog-97b +++ b/ChangeLog-97b @@ -1,5 +1,21 @@ Tue Sep 2 18:26:22 1997 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + * ace/Task: Revised the ACE_Task_Base::svc_run() method to + register a thread exit hook (ACE_Task_Base::cleanup()) + + * ace/Task: Added a static method called cleanup() that can serve + as a thread exit hook to ensure that close() is always called + when a task exits a thread. + + * ace/Thread_Manager: Added the first-cut implementation of the + thread exit hooks. This one is butt-simple -- just allowing a + single hook per-thread, but that should be enough to get us over + the hump... + + * ace/OS.h: Moved the object_info_t type from Object_Manager.h and + renamed it to ACE_Cleanup_Info since we will use it with the + Thread_Manager and the Object_Manager. + * ChangeLog-97b: Emptied out the ChangeLog-97b file until we move the ChangeLog to this file... @@ -2957,6 +2957,20 @@ struct ACE_Export ACE_Str_Buf : public strbuf // <ACE_Object_Manager> and the <ACE_Thread_Manager>. typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */; +struct ACE_Cleanup_Info + // = TITLE + // Hold cleanup information for thread/process +{ + void *object_; + // Point to object that gets passed into the <cleanup_hook_>. + + ACE_CLEANUP_FUNC cleanup_hook_; + // Cleanup hook that gets called back. + + void *param_; + // Parameter passed to the <cleanup_hook_>. +}; + // Run the thread entry point for the <ACE_Thread_Adapter>. This must // be an extern "C" to make certain compilers happy... extern "C" void *ace_thread_adapter (void *args); diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp index 3c788fbff94..ac6c32fd739 100644 --- a/ace/Object_Manager.cpp +++ b/ace/Object_Manager.cpp @@ -17,7 +17,7 @@ ACE_Object_Manager *ACE_Object_Manager::instance_ = 0; ACE_Object_Manager::ACE_Object_Manager (void) : shutting_down_(0) { - ACE_NEW (registered_objects_, ACE_Unbounded_Queue<object_info_t>); + ACE_NEW (registered_objects_, ACE_Unbounded_Queue<ACE_Cleanup_Info>); #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) // Store the address of this static instance so that instance () @@ -33,7 +33,7 @@ ACE_Object_Manager::ACE_Object_Manager (void) ACE_Object_Manager::~ACE_Object_Manager (void) { - object_info_t info; + ACE_Cleanup_Info info; // This call closes and deletes all ACE library services and // singletons. @@ -92,8 +92,8 @@ ACE_Object_Manager::at_exit_i (void *object, return -1; // Check for already in queue, and return 1 if so. - object_info_t *info = 0; - for (ACE_Unbounded_Queue_Iterator<object_info_t> iter (*registered_objects_); + ACE_Cleanup_Info *info = 0; + for (ACE_Unbounded_Queue_Iterator<ACE_Cleanup_Info> iter (*registered_objects_); iter.next (info) != 0; iter.advance ()) { @@ -104,7 +104,7 @@ ACE_Object_Manager::at_exit_i (void *object, } } - object_info_t new_info; + ACE_Cleanup_Info new_info; new_info.object_ = object; new_info.cleanup_hook_ = cleanup_hook; new_info.param_ = param; @@ -115,11 +115,11 @@ ACE_Object_Manager::at_exit_i (void *object, } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Unbounded_Queue<ACE_Object_Manager::object_info_t>; -template class ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::object_info_t>; -template class ACE_Node<ACE_Object_Manager::object_info_t>; +template class ACE_Unbounded_Queue<ACE_Object_Manager::ACE_Cleanup_Info>; +template class ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::ACE_Cleanup_Info>; +template class ACE_Node<ACE_Object_Manager::ACE_Cleanup_Info>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Unbounded_Queue<ACE_Object_Manager::object_info_t> -#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::object_info_t> -#pragma instantiate ACE_Node<ACE_Object_Manager::object_info_t> +#pragma instantiate ACE_Unbounded_Queue<ACE_Object_Manager::ACE_Cleanup_Info> +#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::ACE_Cleanup_Info> +#pragma instantiate ACE_Node<ACE_Object_Manager::ACE_Cleanup_Info> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h index d7f64f92848..ea66a40d570 100644 --- a/ace/Object_Manager.h +++ b/ace/Object_Manager.h @@ -48,8 +48,6 @@ class ACE_Export ACE_Object_Manager // is likely to change, without providing backward capability. { public: - typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */; - static int at_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param); @@ -74,28 +72,14 @@ public: #endif /* 0 */ private: - // typedef void (*ACE_CONSTRUCT_FUNC)(void *object, void *param); - // not currently used: - static ACE_Object_Manager *instance_; // Singleton pointer. -public: - // For template instantiation, with some compilers that need the - // struct definition to be public. - typedef struct object_info - { - void *object_; - ACE_CLEANUP_FUNC cleanup_hook_; - void *param_; - } object_info_t; - -private: - - ACE_Unbounded_Queue<object_info_t> *registered_objects_; + ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_; // Keeps track of all the registered objects. - int shutting_down_; // Non-zero if this being destroyed + int shutting_down_; + // Non-zero if this being destroyed static ACE_Object_Manager *instance (void); // Accessor to singleton instance. Because static member functions diff --git a/ace/Task.cpp b/ace/Task.cpp index 3ba11b9a36d..034b27f1911 100644 --- a/ace/Task.cpp +++ b/ace/Task.cpp @@ -121,6 +121,18 @@ ACE_Task_Base::activate (long flags, #endif /* ACE_MT_SAFE */ } +void +ACE_Task_Base::cleanup (void *object, void *) +{ + ACE_Task_Base *t = (ACE_Task_Base *) object; + + // The thread count must be decremented first in case the <close> + // hook does something crazy like "delete this". + t->thr_count_dec (); + // @@ Is it possible to pass in the exit status somehow? + t->close (); +} + void * ACE_Task_Base::svc_run (void *args) { @@ -128,6 +140,8 @@ ACE_Task_Base::svc_run (void *args) ACE_Task_Base *t = (ACE_Task_Base *) args; + t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0); + // Call the Task's svc() hook method. return (void *) t->svc (); diff --git a/ace/Task.h b/ace/Task.h index e3a76861d63..905a215f85a 100644 --- a/ace/Task.h +++ b/ace/Task.h @@ -164,6 +164,10 @@ public: // Routine that runs the service routine as a daemon thread. static void *svc_run (void *); + static void cleanup (void *object, void *params); + // Cleanup hook that is called when a thread exits to gracefully + // shutdown an <ACE_Task>. + // = Internal data (should be private...). // private: diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index 97f4ce6cb49..79c19e73b42 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -37,6 +37,19 @@ ACE_Thread_Manager::dump (void) const ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } +int +ACE_Thread_Descriptor::at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + ACE_TRACE ("ACE_Thread_Descriptor::at_exit"); + + this->cleanup_info_.object_ = object; + this->cleanup_info_.cleanup_hook_ = cleanup_hook; + this->cleanup_info_.param_ = param; + return 0; +} + void ACE_Thread_Descriptor::dump (void) const { @@ -343,13 +356,6 @@ ACE_Thread_Exit::status (void) ACE_Thread_Exit::~ACE_Thread_Exit (void) { ACE_TRACE ("ACE_Thread_Exit::~ACE_Thread_Exit"); - -#if 0 - // The thread count must be decremented first in case the <close> - // hook does something crazy like "delete this". - this->t_->thr_count_dec (); - this->t_->close (u_long (this->status_)); -#endif /* 0 */ } // Run the entry point for thread spawned under the control of the @@ -665,6 +671,18 @@ ACE_Thread_Manager::insert_thr (ACE_thread_t t_id, return grp_id; } +// Run the registered hooks when the thread exits. + +void +ACE_Thread_Manager::run_thread_exit_hooks (int i) +{ + ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks"); + + (*this->thr_table_[i].cleanup_info_.cleanup_hook_) + (this->thr_table_[i].cleanup_info_.object_, + this->thr_table_[i].cleanup_info_.param_); +} + // Remove a thread from the pool. Must be called with locks held. void @@ -1026,6 +1044,20 @@ ACE_Thread_Manager::wait_grp (int grp_id) return result; } +int +ACE_Thread_Manager::at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param) +{ + // Locate thread id. + int i = this->find_thread (ACE_Thread::self ()); + + if (i != -1) + return this->thr_table_[i].at_exit (object, cleanup_hook, param); + else + return -1; +} + // Must be called when thread goes out of scope to clean up its table // slot. @@ -1035,11 +1067,17 @@ ACE_Thread_Manager::exit (void *status, int do_thr_exit) ACE_TRACE ("ACE_Thread_Manager::exit"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + // Locate thread id. int i = this->find_thread (ACE_Thread::self ()); - // Locate thread id. if (i != -1) - this->remove_thr (i); + { + // Run all the exit hooks. + this->run_thread_exit_hooks (i); + + // Remove thread descriptor from the table. + this->remove_thr (i); + } if (do_thr_exit) { diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h index 7413eb39997..5ed510c68d6 100644 --- a/ace/Thread_Manager.h +++ b/ace/Thread_Manager.h @@ -53,8 +53,20 @@ public: void dump (void) const; // Dump the state of an object. -private: + int at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param); + // Register an object (or array) for cleanup at thread termination. + // "cleanup_hook" points to a (global, or static member) function + // that is called for the object or array when it to be destroyed. + // It may perform any necessary cleanup specific for that object or + // its class. "param" is passed as the second parameter to the + // "cleanup_hook" function; the first parameter is the object (or + // array) to be destroyed. Returns 0 on success, non-zero on + // failure: -1 if virtual memory is exhausted or 1 if the object (or + // arrayt) had already been registered. +private: ACE_thread_t thr_id_; // Unique thread ID. @@ -66,6 +78,11 @@ private: ACE_Thread_State thr_state_; // Current state of the thread. + + ACE_Cleanup_Info cleanup_info_; + // Stores the cleanup info for a thread. + // @@ Note, this should be generalized to be a stack of + // <ACE_Cleanup_Info>s. }; // Forward declaration. @@ -282,6 +299,18 @@ public: int set_grp (ACE_Task_Base *task, int grp_id); int get_grp (ACE_Task_Base *task, int &grp_id); + int at_exit (void *object, + ACE_CLEANUP_FUNC cleanup_hook, + void *param); + // Register an object (or array) for cleanup at thread termination. + // "cleanup_hook" points to a (global, or static member) function + // that is called for the object or array when it to be destroyed. + // It may perform any necessary cleanup specific for that object or + // its class. "param" is passed as the second parameter to the + // "cleanup_hook" function; the first parameter is the object (or + // array) to be destroyed. "cleanup_hook", for example, may delete + // the object (or array). + void dump (void) const; // Dump the state of an object. @@ -301,7 +330,9 @@ protected: ACE_Task_Base *task = 0); // Create a new thread (must be called with locks held). -protected: + void run_thread_exit_hooks (int i); + // Run the registered hooks when the thread exits. + int resize (size_t); // Resize the pool of Thread_Descriptors. |