summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2006-04-14 17:23:39 +0000
committerSteve Huston <shuston@riverace.com>2006-04-14 17:23:39 +0000
commit144a5cd7004316b511ca8003e2972c29521f66fe (patch)
tree1968eaef08badffda1bbe54a4315c17ee40a47be
parentfa92d4711fb7519995b6bb9e5a16016d7326bbb0 (diff)
downloadATCD-144a5cd7004316b511ca8003e2972c29521f66fe.tar.gz
ChangeLogTag:Fri Apr 14 15:53:21 UTC 2006 Steve Huston <shuston@riverace.com>
-rw-r--r--ChangeLog32
-rw-r--r--NEWS11
-rw-r--r--ace/Task.cpp12
-rw-r--r--ace/Task.h3
-rw-r--r--ace/Task.inl16
-rw-r--r--examples/Threads/task_three.cpp12
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:
diff --git a/NEWS b/NEWS
index f01562db0a3..744990117fe 100644
--- a/NEWS
+++ b/NEWS
@@ -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"),