summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ace/Thread_Manager.cpp21
-rw-r--r--ace/Thread_Manager.h4
2 files changed, 19 insertions, 6 deletions
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp
index b742772d5fa..e29f2fe96cd 100644
--- a/ace/Thread_Manager.cpp
+++ b/ace/Thread_Manager.cpp
@@ -473,6 +473,7 @@ ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func,
// <lock_> held...
#if 1
ACE_Thread_Descriptor *new_thr_desc = this->thread_desc_freelist_.remove ();
+ new_thr_desc->registered_ = 0;
// Get a "new" Thread Descriptor from the freelist.
new_thr_desc->sync_->acquire ();
@@ -700,6 +701,7 @@ ACE_Thread_Manager::append_thr (ACE_thread_t t_id,
thr_desc->flags_ = flags;
this->thr_list_.insert_head (thr_desc);
+ thr_desc->registered_ = 1;
thr_desc->sync_->release ();
return 0;
@@ -804,10 +806,19 @@ ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td,
{
ACE_TRACE ("ACE_Thread_Manager::remove_thr");
- td->sync_->acquire ();
- // Acquire the lock before removing <td> from the thread table. If
- // this thread is in the table already, it should simply acquire the
- // lock easily.
+ if (td->registered_ == 0)
+ {
+ td->sync_->acquire ();
+ // Acquire the lock before removing <td> from the thread table. If
+ // this thread is in the table already, it should simply acquire the
+ // lock easily.
+
+ // Once we get the lock, we must have registered.
+ ACE_ASSERT (td->registered_ != 0);
+
+ td->sync_->release ();
+ // Release the lock before putting it back to freelist.
+ }
#if defined (VXWORKS)
ACE_thread_t tid = td->self ();
@@ -830,8 +841,6 @@ ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td,
#endif /* ACE_WIN32 */
#if 1
- td->sync_->release ();
- // Release the lock before putting it back to freelist.
this->thread_desc_freelist_.add (td);
#else
diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h
index 06860d9f022..d3e333d78e8 100644
--- a/ace/Thread_Manager.h
+++ b/ace/Thread_Manager.h
@@ -165,6 +165,10 @@ private:
// <ACE_Task_Base>;
ACE_DEFAULT_THREAD_MANAGER_LOCK *sync_;
+ // Registration lock to prevent premature removal of thread descriptor.
+
+ int registered_;
+ // Keep track of registration status.
ACE_Thread_Descriptor *next_;
ACE_Thread_Descriptor *prev_;