summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-10-27 08:11:47 +0000
committernanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-10-27 08:11:47 +0000
commite74ca4f1c2b3d5443a3bf04f5484bcb556b8d4fa (patch)
treec778bd094760ed060d4f05d40e624569b487c674
parent476754256b0839aa21396dc382d59e17007d861c (diff)
downloadATCD-e74ca4f1c2b3d5443a3bf04f5484bcb556b8d4fa.tar.gz
Applied Detlef's fixed for cond_timedwait/cond_broadcast deadlock problem.
-rw-r--r--ace/OS.i35
1 files changed, 20 insertions, 15 deletions
diff --git a/ace/OS.i b/ace/OS.i
index 3b54779aab5..07d7798f744 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -3400,6 +3400,8 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+ int continue_op = 1;
+
# if defined (ACE_WIN32)
if (result != WAIT_OBJECT_0)
{
@@ -3410,6 +3412,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
break;
default:
error = ::GetLastError ();
+ continue_op = 0;
break;
}
result = -1;
@@ -3424,6 +3427,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
break;
default:
error = errno;
+ continue_op = 0;
break;
}
result = -1;
@@ -3438,6 +3442,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
break;
default:
error = errno;
+ continue_op = 0;
break;
}
result = -1;
@@ -3446,7 +3451,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
# if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
else if (external_mutex->type_ == USYNC_PROCESS)
{
- if (last_waiter)
+ if (last_waiter && continue_op)
// This call atomically signals the <waiters_done_> event and
// waits until it can acquire the mutex. This is important to
// prevent unfairness.
@@ -3465,7 +3470,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
/* NOTREACHED */
}
# endif /* ACE_HAS_SIGNAL_OBJECT_AND_WAIT */
- else if (last_waiter)
+ else if (last_waiter && continue_op)
// Release the signaler/broadcaster if we're the last waiter.
# if defined (ACE_WIN32)
ACE_OS::event_signal (&cv->waiters_done_);
@@ -3551,22 +3556,22 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
- if (result != WAIT_OBJECT_0)
+ switch (result)
{
- switch (result)
- {
- case WAIT_TIMEOUT:
- error = ETIME;
- break;
- default:
- error = ::GetLastError ();
- break;
- }
+ case WAIT_TIMEOUT:
+ error = ETIME;
+ result = -1;
+ // Fall thru purposely
+ case WAIT_OBJECT_0:
+ if (last_waiter)
+ // Release the signaler/broadcaster if we're the last waiter.
+ ACE_OS::event_signal (&cv->waiters_done_);
+ break;
+ default:
+ error = ::GetLastError ();
result = -1;
+ break;
}
- else if (last_waiter)
- // Release the signaler/broadcaster if we're the last waiter.
- ACE_OS::event_signal (&cv->waiters_done_);
// We must always regain the <external_mutex>, even when errors
// occur because that's the guarantee that we give to our callers.