htl: Make pthread*_cond_timedwait register wref before releasing mutex

Otherwise another thread could be rightly trying to destroy the condition,
see e.g. tst-cond20.
This commit is contained in:
Samuel Thibault 2022-08-22 22:27:24 +02:00
parent 8bf0bc8350
commit 4565083abc
2 changed files with 12 additions and 8 deletions

View File

@ -142,13 +142,15 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
__pthread_mutex_unlock (&self->cancel_lock); __pthread_mutex_unlock (&self->cancel_lock);
/* Increase the waiter reference count. Relaxed MO is sufficient because
we only need to synchronize when decrementing the reference count.
We however need to have the mutex held to prevent concurrency with
a pthread_cond_destroy. */
atomic_fetch_add_relaxed (&cond->__wrefs, 2);
/* Release MUTEX before blocking. */ /* Release MUTEX before blocking. */
__pthread_mutex_unlock (mutex); __pthread_mutex_unlock (mutex);
/* Increase the waiter reference count. Relaxed MO is sufficient because
we only need to synchronize when decrementing the reference count. */
atomic_fetch_add_relaxed (&cond->__wrefs, 2);
/* Block the thread. */ /* Block the thread. */
if (abstime != NULL) if (abstime != NULL)
err = __pthread_timedblock (self, abstime, clock_id); err = __pthread_timedblock (self, abstime, clock_id);

View File

@ -103,6 +103,12 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
__pthread_spin_unlock (&cond->__lock); __pthread_spin_unlock (&cond->__lock);
__spin_unlock (&ss->lock); __spin_unlock (&ss->lock);
/* Increase the waiter reference count. Relaxed MO is sufficient because
we only need to synchronize when decrementing the reference count.
We however need to have the mutex held to prevent concurrency with
a pthread_cond_destroy. */
atomic_fetch_add_relaxed (&cond->__wrefs, 2);
if (cancel) if (cancel)
{ {
/* Cancelled on entry. Just leave the mutex locked. */ /* Cancelled on entry. Just leave the mutex locked. */
@ -115,10 +121,6 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
/* Release MUTEX before blocking. */ /* Release MUTEX before blocking. */
__pthread_mutex_unlock (mutex); __pthread_mutex_unlock (mutex);
/* Increase the waiter reference count. Relaxed MO is sufficient because
we only need to synchronize when decrementing the reference count. */
atomic_fetch_add_relaxed (&cond->__wrefs, 2);
/* Block the thread. */ /* Block the thread. */
if (abstime != NULL) if (abstime != NULL)
err = __pthread_timedblock (self, abstime, clock_id); err = __pthread_timedblock (self, abstime, clock_id);