diff options
author | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-10-27 08:11:47 +0000 |
---|---|---|
committer | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-10-27 08:11:47 +0000 |
commit | e74ca4f1c2b3d5443a3bf04f5484bcb556b8d4fa (patch) | |
tree | c778bd094760ed060d4f05d40e624569b487c674 | |
parent | 476754256b0839aa21396dc382d59e17007d861c (diff) | |
download | ATCD-e74ca4f1c2b3d5443a3bf04f5484bcb556b8d4fa.tar.gz |
Applied Detlef's fixed for cond_timedwait/cond_broadcast deadlock problem.
-rw-r--r-- | ace/OS.i | 35 |
1 files changed, 20 insertions, 15 deletions
@@ -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. |