* pthread_cond_destroy.c (__pthread_cond_destroy): If there are

waiters, awake all waiters on the associated mutex.
This commit is contained in:
Ulrich Drepper 2005-09-25 23:58:51 +00:00
parent 9c5a790487
commit 560b47093f
2 changed files with 30 additions and 5 deletions

View File

@ -1,3 +1,8 @@
2004-09-02 Jakub Jelinek <jakub@redhat.com>
* pthread_cond_destroy.c (__pthread_cond_destroy): If there are
waiters, awake all waiters on the associated mutex.
2005-09-22 Roland McGrath <roland@redhat.com> 2005-09-22 Roland McGrath <roland@redhat.com>
* perf.c [__x86_64__] (HP_TIMING_NOW): New macro (copied from * perf.c [__x86_64__] (HP_TIMING_NOW): New macro (copied from

View File

@ -44,15 +44,35 @@ __pthread_cond_destroy (cond)
broadcasted, but still are using the pthread_cond_t structure, broadcasted, but still are using the pthread_cond_t structure,
pthread_cond_destroy needs to wait for them. */ pthread_cond_destroy needs to wait for them. */
unsigned int nwaiters = cond->__data.__nwaiters; unsigned int nwaiters = cond->__data.__nwaiters;
while (nwaiters >= (1 << COND_CLOCK_BITS))
if (nwaiters >= (1 << COND_CLOCK_BITS))
{ {
lll_mutex_unlock (cond->__data.__lock); /* Wake everybody on the associated mutex in case there are
threads that have been requeued to it.
Without this, pthread_cond_destroy could block potentially
for a long time or forever, as it would depend on other
thread's using the mutex.
When all threads waiting on the mutex are woken up, pthread_cond_wait
only waits for threads to acquire and release the internal
condvar lock. */
if (cond->__data.__mutex != NULL
&& cond->__data.__mutex != (void *) ~0l)
{
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
lll_futex_wake (&mut->__data.__lock, INT_MAX);
}
lll_futex_wait (&cond->__data.__nwaiters, nwaiters); do
{
lll_mutex_unlock (cond->__data.__lock);
lll_mutex_lock (cond->__data.__lock); lll_futex_wait (&cond->__data.__nwaiters, nwaiters);
nwaiters = cond->__data.__nwaiters; lll_mutex_lock (cond->__data.__lock);
nwaiters = cond->__data.__nwaiters;
}
while (nwaiters >= (1 << COND_CLOCK_BITS));
} }
return 0; return 0;