summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-04 20:56:15 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-09-04 20:56:15 +0000
commit741372ffe051856ce3b2ffdc67a6fe257d2e0e1d (patch)
treee148422332f27475332161ad77c6ab43c1ef712a /ace
parent28cd31dc036e6aa82d7d87740924b0aa1f1ba3ae (diff)
downloadATCD-741372ffe051856ce3b2ffdc67a6fe257d2e0e1d.tar.gz
(dump,kill_thr): added guard because thr_table_ is accessed. (wait): hacked in thr_yield () to give waited threads a chance to clean up
Diffstat (limited to 'ace')
-rw-r--r--ace/Thread_Manager.cpp64
1 files changed, 41 insertions, 23 deletions
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp
index 8a1e6eee26c..aed9f7a68fb 100644
--- a/ace/Thread_Manager.cpp
+++ b/ace/Thread_Manager.cpp
@@ -25,6 +25,10 @@ void
ACE_Thread_Manager::dump (void) const
{
ACE_TRACE ("ACE_Thread_Manager::dump");
+ // Cast away const-ness of this in order to use its non-const lock_.
+ ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon,
+ ((ACE_Thread_Manager *) this)->lock_));
+
ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
ACE_DEBUG ((LM_DEBUG, "\ngrp_id_ = %d", this->grp_id_));
@@ -65,7 +69,9 @@ ACE_Thread_Descriptor::dump (void) const
}
ACE_Thread_Descriptor::ACE_Thread_Descriptor (void)
- : thr_id_ (ACE_OS::NULL_thread),
+ : task_ (0),
+ thr_id_ (ACE_OS::NULL_thread),
+ thr_handle_ (ACE_OS::NULL_hthread),
grp_id_ (0),
thr_state_ (ACE_THR_IDLE)
{
@@ -136,19 +142,14 @@ ACE_Thread_Manager::resize (size_t size)
ACE_NEW_RETURN (temp, ACE_Thread_Descriptor[size], -1);
- size_t i;
-
- for (i = 0; i < this->max_table_size_; i++)
+ for (size_t i = 0; i < this->max_table_size_; i++)
temp[i] = this->thr_table_[i]; // Structure assignment.
- for (; i < size; i++)
- temp[i].cleanup_info_.cleanup_hook_ = 0; // Zero unused table slots.
-
this->max_table_size_ = size;
delete [] this->thr_table_;
-
this->thr_table_ = temp;
+
return 0;
}
@@ -206,7 +207,6 @@ ACE_Thread_Manager *
ACE_Thread_Manager::instance (ACE_Thread_Manager *tm)
{
ACE_TRACE ("ACE_Thread_Manager::instance");
-
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
*ACE_Static_Object_Lock::instance (), 0));
@@ -240,7 +240,6 @@ int
ACE_Thread_Manager::close (void)
{
ACE_TRACE ("ACE_Thread_Manager::close");
-
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
if (this->thr_table_ != 0)
@@ -486,14 +485,16 @@ ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func,
if (result != 0)
{
// _Don't_ clobber errno here! result is either 0 or -1, and
- // ACE_OS::thr_create () already set errno! D. Levine 28 Mar
- // 1997 errno = result;
+ // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997
+ // errno = result;
return -1;
}
else
- return this->append_thr (*t_id, *t_handle,
- ACE_THR_SPAWNED,
- grp_id, task);
+ {
+ return this->append_thr (*t_id, *t_handle,
+ ACE_THR_SPAWNED,
+ grp_id, task);
+ }
}
// Create a new thread running <func>. *Must* be called with the
@@ -773,6 +774,7 @@ int
ACE_Thread_Manager::kill_thr (int i, int arg)
{
ACE_TRACE ("ACE_Thread_Manager::kill_thr");
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
int signum = (int) arg;
@@ -1121,14 +1123,32 @@ int
ACE_Thread_Manager::wait (const ACE_Time_Value *timeout)
{
ACE_TRACE ("ACE_Thread_Manager::wait");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
#if defined (ACE_HAS_THREADS)
- while (this->current_count_ > 0)
- {
- if (this->zero_cond_.wait (timeout) == -1)
- return -1;
- }
+ size_t threads_waited_on;
+
+ // Just hold onto the guard while waiting.
+ {
+ ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
+
+ threads_waited_on = this->current_count_;
+
+ while (this->current_count_ > 0)
+ {
+ if (this->zero_cond_.wait (timeout) == -1)
+ return -1;
+ }
+ }
+ // Let go of the guard, giving other threads a chance to run.
+
+ // Yield (twice) for each thread that we had to wait on. This
+ // should give each of those threads a chance to clean up. The
+ // problem arises because the threads that signalled zero_cond_ may
+ // not have had a chance to run after that, and therefore may not
+ // have finished cleaning themselves up. This isn't a guaranteed
+ // fix, of course, but that would be very complicated.
+ for (size_t i = 0; i < 2 * threads_waited_on; ++i)
+ ACE_OS::thr_yield ();
#else
ACE_UNUSED_ARG (timeout);
#endif /* ACE_HAS_THREADS */
@@ -1358,7 +1378,6 @@ int
ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id)
{
ACE_TRACE ("ACE_Thread_Manager::set_grp");
-
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
for (size_t i = 0; i < this->current_count_; i++)
@@ -1371,7 +1390,6 @@ int
ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id)
{
ACE_TRACE ("ACE_Thread_Manager::get_grp");
-
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
ACE_FIND (this->find_task (task), index);