winpthreads/cond.c: Remove waits for sema_b from wait functions.

All other functions wait for `sema_b` with `waiters_count_lock_` locked.
The order of acquisition of these two things must happen in the same order
in all functions, otherwise deadlocks may happen.

The obvious fix is to make wait functions wait for the semaphore after
having locked `waiters_count_lock_`. However, before the wait, the critical
seciton must be unlocked, otherwise all the other threads will be blocked
on signal/broadcast functions. The now consequent wait and signal operations
on the semaphore have no other effect and can be removed.

From now on, waiting threads will update `waiters_count_` without attempting
to lock `sema_b`. If a wait function is called under the protection of the
external mutex, this was unnecessary; otherwise, scheduling behavior might be
unpredictable, which nevertheless still conforms to POSIX.

Signed-off-by: Liu Hao <lh_mouse@126.com>
This commit is contained in:
Liu Hao 2019-04-26 14:09:00 +08:00
parent 2a439e13bc
commit b2302cd60b

View File

@ -431,15 +431,9 @@ pthread_cond_wait (pthread_cond_t *c, pthread_mutex_t *external_mutex)
} else if (_c->valid != (unsigned int)LIFE_COND)
return EINVAL;
r = do_sema_b_wait (_c->sema_b, 0, INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
EnterCriticalSection (&_c->waiters_count_lock_);
_c->waiters_count_++;
LeaveCriticalSection(&_c->waiters_count_lock_);
r = do_sema_b_release (_c->sema_b, 1,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
ch.c = _c;
ch.r = &r;
@ -485,15 +479,9 @@ pthread_cond_timedwait_impl (pthread_cond_t *c, pthread_mutex_t *external_mutex,
dwr = dwMilliSecs(_pthread_time_in_ms_from_timespec(t));
}
r = do_sema_b_wait (_c->sema_b, 0, INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
EnterCriticalSection (&_c->waiters_count_lock_);
_c->waiters_count_++;
LeaveCriticalSection(&_c->waiters_count_lock_);
r = do_sema_b_release (_c->sema_b, 1,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
ch.c = _c;
ch.r = &r;