aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/mach/hurd/htl
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach/hurd/htl')
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
index 939ed56..4f63955 100644
--- a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
@@ -111,6 +111,10 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
/* Release MUTEX before blocking. */
__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. */
if (abstime != NULL)
err = __pthread_timedblock (self, abstime, clock_id);
@@ -144,6 +148,13 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
__pthread_block (self);
}
+ /* If destruction is pending (i.e., the wake-request flag is nonzero) and we
+ are the last waiter (prior value of __wrefs was 1 << 1), then wake any
+ threads waiting in pthread_cond_destroy. Release MO to synchronize with
+ these threads. Don't bother clearing the wake-up request flag. */
+ if ((atomic_fetch_add_release (&cond->__wrefs, -2)) == 3)
+ __gsync_wake (__mach_task_self (), (vm_offset_t) &cond->__wrefs, 0, 0);
+
/* Clear the hook, now that we are done blocking. */
ss->cancel_hook = NULL;
/* Check the cancellation flag; we might have unblocked due to