diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-09-25 23:58:51 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-09-25 23:58:51 +0000 |
commit | 560b47093fedfc210e2020d93c20fcfe3e620312 (patch) | |
tree | 67299737972434af7a2a89d8c64a520dc612dff8 | |
parent | 9c5a79048766f0ac89aa84ad0c9a2f6e6dffec17 (diff) | |
download | glibc-560b47093fedfc210e2020d93c20fcfe3e620312.zip glibc-560b47093fedfc210e2020d93c20fcfe3e620312.tar.gz glibc-560b47093fedfc210e2020d93c20fcfe3e620312.tar.bz2 |
* pthread_cond_destroy.c (__pthread_cond_destroy): If there are
waiters, awake all waiters on the associated mutex.
-rw-r--r-- | nptl/ChangeLog | 5 | ||||
-rw-r--r-- | nptl/pthread_cond_destroy.c | 30 |
2 files changed, 30 insertions, 5 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 4884cc2..8e48cfd 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -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> * perf.c [__x86_64__] (HP_TIMING_NOW): New macro (copied from diff --git a/nptl/pthread_cond_destroy.c b/nptl/pthread_cond_destroy.c index 0208d18..3e4ec8d 100644 --- a/nptl/pthread_cond_destroy.c +++ b/nptl/pthread_cond_destroy.c @@ -44,15 +44,35 @@ __pthread_cond_destroy (cond) broadcasted, but still are using the pthread_cond_t structure, pthread_cond_destroy needs to wait for them. */ 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); + } + + do + { + lll_mutex_unlock (cond->__data.__lock); - lll_futex_wait (&cond->__data.__nwaiters, nwaiters); + lll_futex_wait (&cond->__data.__nwaiters, nwaiters); - lll_mutex_lock (cond->__data.__lock); + lll_mutex_lock (cond->__data.__lock); - nwaiters = cond->__data.__nwaiters; + nwaiters = cond->__data.__nwaiters; + } + while (nwaiters >= (1 << COND_CLOCK_BITS)); } return 0; |