diff options
author | nw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-12-02 21:11:58 +0000 |
---|---|---|
committer | nw1 <nw1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-12-02 21:11:58 +0000 |
commit | faca59d934418cca8f70f6f0c476f7a042e97469 (patch) | |
tree | 0629d66dfc13b9aa8fa4c99a314fcd847a7650cb | |
parent | a172d3fb572733e5b15f06f2b22162affbdb9e33 (diff) | |
download | ATCD-faca59d934418cca8f70f6f0c476f7a042e97469.tar.gz |
Furthre refine wait mechanism. See ChangeLog entry of Dec. 2 1997.
-rw-r--r-- | ace/Thread_Manager.cpp | 81 | ||||
-rw-r--r-- | ace/Thread_Manager.h | 3 |
2 files changed, 52 insertions, 32 deletions
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index 18a03671e2a..774d9094786 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -232,9 +232,6 @@ ACE_Thread_Manager::close_singleton (void) if (ACE_Thread_Manager::delete_thr_mgr_) { -#if defined (ACE_WIN32) - ACE_Thread_Manager::thr_mgr_->wait_on_exit (0); -#endif /* ACE_WIN32 */ // First, we clean up the thread descriptor list. ACE_Thread_Manager::thr_mgr_->close (); delete ACE_Thread_Manager::thr_mgr_; @@ -256,17 +253,8 @@ ACE_Thread_Manager::close () else { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - ACE_Thread_Descriptor *td; - while ((td = this->thr_list_.delete_head ()) != 0) - { -#if defined (ACE_WIN32) - // We need to let go handles if we want to let the threads - // run wild. - // @@ Do we need to close down AIX thread handles too? - ::CloseHandle (td->thr_handle_); -#endif /* ACE_WIN32 */ - delete td; - } + + this->remove_thr_all (); } return 0; @@ -795,6 +783,27 @@ ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td, #endif /* ACE_HAS_THREADS */ } +// Repeatedly call remove_thr on all table entries until there +// is no thread left. Must be called with lock held. + +void +ACE_Thread_Manager::remove_thr_all (void) +{ + ACE_Thread_Descriptor *td; + + while ((td = this->thr_list_.delete_head ()) != 0) + { +#if defined (ACE_WIN32) + // We need to let go handles if we want to let the threads + // run wild. + // @@ Do we need to close down AIX thread handles too? + ::CloseHandle (td->thr_handle_); +#endif /* ACE_WIN32 */ + delete td; + } + +} + // ------------------------------------------------------------------ // Factor out some common behavior to simplify the following methods. #define ACE_THR_OP(OP,STATE) \ @@ -1299,28 +1308,36 @@ ACE_Thread_Manager::wait (const ACE_Time_Value *timeout, // Just hold onto the guard while waiting. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); - if (abandon_detached_threads != 0) + if (ACE_Object_Manager::shutting_down () != 1) { - ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); - for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); - !iter.done (); - iter.advance ()) - if (ACE_BIT_ENABLED (iter.next ()->flags_, (THR_DETACHED | THR_DAEMON)) && - ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE)) - this->thr_to_be_removed_.enqueue_tail (iter.next ()); - - if (! this->thr_to_be_removed_.is_empty ()) + // Program is not shutting down. Perform a normal wait on threads. + if (abandon_detached_threads != 0) { - ACE_Thread_Descriptor *td; - while (this->thr_to_be_removed_.dequeue_head (td) != -1) - this->remove_thr (td, 0); + ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); + for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> + iter (this->thr_list_); + !iter.done (); + iter.advance ()) + if (ACE_BIT_ENABLED (iter.next ()->flags_, (THR_DETACHED | THR_DAEMON)) && + ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE)) + this->thr_to_be_removed_.enqueue_tail (iter.next ()); + + if (! this->thr_to_be_removed_.is_empty ()) + { + ACE_Thread_Descriptor *td; + while (this->thr_to_be_removed_.dequeue_head (td) != -1) + this->remove_thr (td, 1); + } } - } - - while (this->thr_list_.size () > 0) - if (this->zero_cond_.wait (timeout) == -1) - return -1; + while (this->thr_list_.size () > 0) + if (this->zero_cond_.wait (timeout) == -1) + return -1; + } + else + // Program is shutting down, no chance to wait on threads. + // Therefore, we'll just remove threads from the list. + this->remove_thr_all (); // Release the guard, giving other threads a chance to run. } diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h index e06977469a7..a1ed03a9e9d 100644 --- a/ace/Thread_Manager.h +++ b/ace/Thread_Manager.h @@ -437,6 +437,9 @@ protected: void remove_thr (ACE_Thread_Descriptor *td, int close_handler); // Remove thread from the table. + void remove_thr_all (void); + // Remove all threads from the table. + // = The following four methods implement a simple scheme for // operating on a collection of threads atomically. |