diff options
author | Adam Mitz <mitza@ociweb.com> | 2015-11-06 17:07:11 -0600 |
---|---|---|
committer | Adam Mitz <mitza@ociweb.com> | 2015-11-06 17:07:11 -0600 |
commit | ac5e1702c9f9bee9f1f7bfce8c1a6f3847ea6b4b (patch) | |
tree | 0e70d1f51c39e688a05a6cdc2af58408222e4a0d /ACE/ace/Thread_Manager.cpp | |
parent | 5272b5b81f92c298cb998b5bb0b0dbca3e7f29fe (diff) | |
download | ATCD-ac5e1702c9f9bee9f1f7bfce8c1a6f3847ea6b4b.tar.gz |
Merged branch ace-face-safety (FACE Safety Profile import from OCITAO).
Diffstat (limited to 'ACE/ace/Thread_Manager.cpp')
-rw-r--r-- | ACE/ace/Thread_Manager.cpp | 146 |
1 files changed, 135 insertions, 11 deletions
diff --git a/ACE/ace/Thread_Manager.cpp b/ACE/ace/Thread_Manager.cpp index 657ac9f3500..94b25f7063f 100644 --- a/ACE/ace/Thread_Manager.cpp +++ b/ACE/ace/Thread_Manager.cpp @@ -25,6 +25,8 @@ ACE_At_Thread_Exit_Func::~ACE_At_Thread_Exit_Func (void) this->do_apply (); } +ACE_ALLOC_HOOK_DEFINE(ACE_At_Thread_Exit_Func) + void ACE_At_Thread_Exit_Func::apply (void) { @@ -368,6 +370,9 @@ ACE_Thread_Manager::ACE_Thread_Manager (size_t prealloc, #endif /* ACE_HAS_THREADS */ , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL, prealloc, lwm, hwm, inc) +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + , join_cond_ (this->lock_) +#endif { ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager"); } @@ -384,6 +389,9 @@ ACE_Thread_Manager::ACE_Thread_Manager (const ACE_Condition_Attributes &attribut #endif /* ACE_HAS_THREADS */ , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL, prealloc, lwm, hwm, inc) +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + , join_cond_ (this->lock_) +#endif { #if !defined (ACE_HAS_THREADS) ACE_UNUSED_ARG (attributes); @@ -993,6 +1001,40 @@ int ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int) { ACE_TRACE ("ACE_Thread_Manager::join_thr"); + +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (ACE_BIT_DISABLED (td->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (td->flags_, THR_JOINABLE)) + { + if (td->terminated_) + return 0; + ACE_SET_BITS (td->thr_state_, ACE_THR_JOINING); + } + else + { + errno = EINVAL; + return -1; + } + + const ACE_thread_t waiting_id = td->thr_id_; + + while (true) + { + if (this->join_cond_.wait () == -1) + return -1; + + bool found = false; + for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); + !iter.done () && !found; iter.advance ()) + if (ACE_OS::thr_equal (iter.next ()->thr_id_, waiting_id)) + found = true; + if (!found) + break; + } + +#else int const result = ACE_Thread::join (td->thr_handle_); if (result != 0) { @@ -1003,6 +1045,7 @@ ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int) errno = result; return -1; } +#endif // ACE_HAS_THREADS && ACE_LACKS_PTHREAD_JOIN return 0; } @@ -1446,10 +1489,12 @@ ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status) if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid)) { ACE_Thread_Descriptor_Base *tdbl = biter.advance_and_remove (false); +#ifndef ACE_LACKS_PTHREAD_JOIN if (ACE_Thread::join (tdbl->thr_handle_, status) == -1) { return -1; } +#endif delete tdbl; // return immediately if we've found the thread we want to join. @@ -1458,9 +1503,8 @@ ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status) } #endif /* !ACE_HAS_VXTHREADS */ - for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); - !iter.done (); - iter.advance ()) + typedef ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter_t; + for (iter_t iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't help much. @@ -1470,7 +1514,7 @@ ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status) { tdb = *iter.next (); ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); - found = 1; + found = true; break; } } @@ -1478,10 +1522,31 @@ ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status) if (!found) return -1; // Didn't find the thread we want or the thread is not joinable. + +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + ACE_UNUSED_ARG (status); // not currently supported without pthread_join + + while (found) + { + if (this->join_cond_.wait () == -1) + return -1; + + found = false; + for (iter_t iter (this->thr_list_); !iter.done () && !found; iter.advance ()) + if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid) && + (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) + found = true; + } + +#endif // ACE_HAS_THREADS && ACE_LACKS_PTHREAD_JOIN + } +#ifndef ACE_LACKS_PTHREAD_JOIN if (ACE_Thread::join (tdb.thr_handle_, status) == -1) return -1; +#endif return 0; } @@ -1513,9 +1578,8 @@ ACE_Thread_Manager::wait_grp (int grp_id) -1); #endif /* !ACE_HAS_VXTHREADS */ - for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); - !iter.done (); - iter.advance ()) + typedef ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter_t; + for (iter_t iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't help much. @@ -1543,6 +1607,28 @@ ACE_Thread_Manager::wait_grp (int grp_id) } } #endif /* !ACE_HAS_VXTHREADS */ + +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + + while (copy_count) + { + if (this->join_cond_.wait () == -1) + { + delete[] copy_table; + return -1; + } + + copy_count = 0; + for (iter_t iter (this->thr_list_); !iter.done () && !copy_count; iter.advance ()) + if (iter.next ()->grp_id_ == grp_id && + ACE_BIT_ENABLED (iter.next ()->thr_state_, ACE_THR_JOINING) && + (ACE_BIT_DISABLED (iter.next ()->flags_, + THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) + ++copy_count; + } + +#endif // ACE_HAS_THREADS && ACE_LACKS_PTHREAD_JOIN } // Now actually join() with all the threads in this group. @@ -1602,6 +1688,10 @@ ACE_Thread_Manager::exit (ACE_THR_FUNC_RETURN status, bool do_thread_exit) // @@ We call Thread_Descriptor terminate this realize the cleanup // process itself. td->terminate(); + +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + this->join_cond_.broadcast (); +#endif } } @@ -1700,11 +1790,12 @@ ACE_Thread_Manager::wait (const ACE_Time_Value *timeout, while ((item = term_thr_list_copy.delete_head ()) != 0) { +#ifndef ACE_LACKS_PTHREAD_JOIN if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON) || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE)) // Detached handles shouldn't reached here. (void) ACE_Thread::join (item->thr_handle_); - +#endif delete item; } @@ -1777,9 +1868,8 @@ ACE_Thread_Manager::wait_task (ACE_Task_Base *task) -1); #endif /* !ACE_HAS_VXTHREADS */ - for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); - !iter.done (); - iter.advance ()) + typedef ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter_t; + for (iter_t iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't wait on them here. @@ -1789,6 +1879,14 @@ ACE_Thread_Manager::wait_task (ACE_Task_Base *task) || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) { +# ifdef ACE_LACKS_PTHREAD_JOIN + if (ACE_OS::thr_equal (iter.next ()->thr_id_, ACE_OS::thr_self ())) + { + errno = EDEADLK; + delete[] copy_table; + return -1; + } +# endif ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); copy_table[copy_count++] = *iter.next (); @@ -1804,11 +1902,35 @@ ACE_Thread_Manager::wait_task (ACE_Task_Base *task) if (titer.next ()->task_ == task) { ACE_Thread_Descriptor_Base *tdb = titer.advance_and_remove (false); +# ifndef ACE_LACKS_PTHREAD_JOIN copy_table[copy_count++] = *tdb; +# endif delete tdb; } } #endif /* !ACE_HAS_VXTHREADS */ + +#if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN) + + while (copy_count) + { + if (this->join_cond_.wait () == -1) + { + delete[] copy_table; + return -1; + } + + copy_count = 0; + for (iter_t iter (this->thr_list_); !iter.done () && !copy_count; iter.advance ()) + if (iter.next ()->task_ == task && + ACE_BIT_ENABLED (iter.next ()->thr_state_, ACE_THR_JOINING) && + (ACE_BIT_DISABLED (iter.next ()->flags_, + THR_DETACHED | THR_DAEMON) + || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) + ++copy_count; + } + +#endif // ACE_HAS_THREADS && ACE_LACKS_PTHREAD_JOIN } // Now to do the actual work @@ -2244,4 +2366,6 @@ ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id) return 0; } +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Descriptor_Base); + ACE_END_VERSIONED_NAMESPACE_DECL |