diff options
author | Steve Huston <shuston@riverace.com> | 2006-04-14 17:23:39 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2006-04-14 17:23:39 +0000 |
commit | 144a5cd7004316b511ca8003e2972c29521f66fe (patch) | |
tree | 1968eaef08badffda1bbe54a4315c17ee40a47be | |
parent | fa92d4711fb7519995b6bb9e5a16016d7326bbb0 (diff) | |
download | ATCD-144a5cd7004316b511ca8003e2972c29521f66fe.tar.gz |
ChangeLogTag:Fri Apr 14 15:53:21 UTC 2006 Steve Huston <shuston@riverace.com>
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | NEWS | 11 | ||||
-rw-r--r-- | ace/Task.cpp | 12 | ||||
-rw-r--r-- | ace/Task.h | 3 | ||||
-rw-r--r-- | ace/Task.inl | 16 | ||||
-rw-r--r-- | examples/Threads/task_three.cpp | 12 |
6 files changed, 71 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index 9c3c90ffff8..7fd481b1121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Fri Apr 14 15:53:21 UTC 2006 Steve Huston <shuston@riverace.com> + + * NEWS: Updated to reflect the changes and fixes below. + + * ace/Task.{h inl cpp}: Change ACE_Task::lock_ from ACE_Thread_Mutex + to ACE_Recursive_Thread_Mutex, and hold lock_ across call to + ACE_Task::close() in ACE_Task_Base::cleanup(). This guards against + multiple threads in close() seeing a 0 thr_count() and acting on it. + Thanks to Howard Finer <hfiner at sonusnet dot com> for this fix. + Fixes Bugzilla #2339. + + * ace/SOCK_Stream.h: Explain more about how the *_n methods work and + how to use the timeout and bytes_transferred arguments. + + * examples/Threads/task_three.cpp: Change name of the file static + ACE_Thread_Mutex from lock_ to Lock to avoid clashing with the + ACE_Task-inherited member lock_. + + * ace/SSL/SSL_Asynch_Stream.{h cpp}: Changes that allow + ACE_SSL_Asynch_Stream objects to be instantiated; required adding + an implementation of the pure virtual implementation() method + inherited from ACE_Asynch_Operation. + Also moved the declaration of the ACE_SSL_Asynch_Read_Stream_Result, + ACE_SSL_Asynch_Write_Stream_Result, and ACE_SSL_Asynch_Result classes + from the .cpp file to the .h file so applications can see them. + Also corrected and enhanced a lot of the documentation. + + * tests/SSL/tests.mpc: + * tests/SSL/Makefile.am: + * tests/SSL/SSL_Asynch_Stream_Test.cpp: Added a new test that at least + tests building an application to use ACE_SSL_Asynch_Stream. + Fri Apr 14 14:57:12 UTC 2006 Chad Elliott <elliott_c@ociweb.com> * bin/msvc_static_compile.pl: @@ -26,6 +26,17 @@ USER VISIBLE CHANGES BETWEEN ACE-5.5 and ACE-5.5.1 . Fixed ACE_SSL_Context::private_key(), context(), and dh_params() methods to allow retrying a file load after a failed call. +. Fixed ACE_SSL_Asynch_Stream so it can be instantiated; also moved the + declarations for ACE_SSL_Asynch_Read_Stream_Result, + ACE_SSL_Asynch_Write_Stream_Result, and ACE_SSL_Asynch_Result classes + to the ace/SSL/SSL_Asynch_Stream.h file so applications can see them. + +. The ACE_Task class's internal lock_ member was changed from an + ACE_Thread_Mutex to ACE_Recursive_Thread_Mutex. Additionally, the lock + is now held by ACE across the call to a task's close() hook when a thread + is shutting down to prevent a race condition where multiple threads may + think they are the last thread (Bugzilla #2339). + USER VISIBLE CHANGES BETWEEN ACE-5.4.10 and ACE-5.5 ==================================================== diff --git a/ace/Task.cpp b/ace/Task.cpp index f92df9a2005..8617e6ec183 100644 --- a/ace/Task.cpp +++ b/ace/Task.cpp @@ -92,7 +92,7 @@ int ACE_Task_Base::suspend (void) { ACE_TRACE ("ACE_Task_Base::suspend"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); if (this->thr_count_ > 0) return this->thr_mgr_->suspend_task (this); @@ -104,7 +104,7 @@ int ACE_Task_Base::resume (void) { ACE_TRACE ("ACE_Task_Base::resume"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); if (this->thr_count_ > 0) return this->thr_mgr_->resume_task (this); @@ -126,7 +126,7 @@ ACE_Task_Base::activate (long flags, ACE_TRACE ("ACE_Task_Base::activate"); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1); // If the task passed in is zero, we will use <this> if (task == 0) @@ -216,9 +216,13 @@ ACE_Task_Base::cleanup (void *object, void *) { ACE_Task_Base *t = (ACE_Task_Base *) object; + // The thread count decrement and close must be done atomically + // so that thr_count checks from within close are correct. + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, t->lock_)); + // The thread count must be decremented first in case the <close> // hook does something crazy like "delete this". - t->thr_count_dec (); + --(t->thr_count_); // @@ Is it possible to pass in the exit status somehow? t->close (); diff --git a/ace/Task.h b/ace/Task.h index 040a15dcbba..130feaeff40 100644 --- a/ace/Task.h +++ b/ace/Task.h @@ -20,6 +20,7 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Recursive_Thread_Mutex.h" #include "ace/Thread_Manager.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL @@ -268,7 +269,7 @@ public: #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) /// Protect the state of a Task during concurrent operations, but /// only if we're configured as MT safe... - ACE_Thread_Mutex lock_; + ACE_Recursive_Thread_Mutex lock_; #endif /* ACE_MT_SAFE */ private: diff --git a/ace/Task.inl b/ace/Task.inl index 5ef5974130f..9343ae057e4 100644 --- a/ace/Task.inl +++ b/ace/Task.inl @@ -23,7 +23,11 @@ ACE_INLINE size_t ACE_Task_Base::thr_count (void) const { ACE_TRACE ("ACE_Task_Base::thr_count"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast <ACE_Thread_Mutex&>(this->lock_), 0)); + ACE_MT + (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + const_cast <ACE_Recursive_Thread_Mutex&>(this->lock_), + 0)); return this->thr_count_; } @@ -34,7 +38,7 @@ ACE_INLINE void ACE_Task_Base::thr_count_dec (void) { ACE_TRACE ("ACE_Task_Base::thr_count_dec"); - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_)); this->thr_count_--; } @@ -58,7 +62,11 @@ ACE_INLINE int ACE_Task_Base::grp_id (void) const { ACE_TRACE ("ACE_Task_Base::grp_id"); - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast <ACE_Thread_Mutex&>(this->lock_), -1)); + ACE_MT + (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, + ace_mon, + const_cast <ACE_Recursive_Thread_Mutex&>(this->lock_), + -1)); return this->grp_id_; } @@ -68,7 +76,7 @@ ACE_INLINE void ACE_Task_Base::grp_id (int identifier) { ACE_TRACE ("ACE_Task_Base::grp_id"); - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_)); // Cache the group id in the task and then set it in the // Thread_Manager, if there is one. diff --git a/examples/Threads/task_three.cpp b/examples/Threads/task_three.cpp index c1e796736ad..03f6e816572 100644 --- a/examples/Threads/task_three.cpp +++ b/examples/Threads/task_three.cpp @@ -53,11 +53,11 @@ public: size_t Test_Task::current_count_ = 0; size_t Test_Task::done_cnt_ = 0; -static ACE_Thread_Mutex lock_; +static ACE_Thread_Mutex Lock; Test_Task::Test_Task (void) { - ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + ACE_GUARD (ACE_Thread_Mutex, ace_mon, Lock); this->handled_ = 0; Test_Task::current_count_++; @@ -68,7 +68,7 @@ Test_Task::Test_Task (void) Test_Task::~Test_Task (void) { - ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + ACE_GUARD (ACE_Thread_Mutex, ace_mon, Lock); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Test_Task destroyed, current_count_ = %d\n"), @@ -85,7 +85,7 @@ Test_Task::open (void *args) int Test_Task::close (u_long) { - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Lock, -1); Test_Task::current_count_--; ACE_DEBUG ((LM_DEBUG, @@ -110,7 +110,7 @@ Test_Task::svc (void) if (r_->notify (this, ACE_Event_Handler::READ_MASK) == -1) { - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Lock, -1); ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Test_Task: error %p!\n"), @@ -130,7 +130,7 @@ Test_Task::handle_input (ACE_HANDLE) if (this->handled_ == NUM_INVOCATIONS) { - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Lock, -1); Test_Task::done_cnt_++; ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) Test_Task: handle_input done_cnt_ = %d.\n"), |