diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2017-10-28 21:25:25 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2017-10-28 21:25:25 +0000 |
commit | 7c90e1a78a1b6a1d524aa57c159d08a51ef9df17 (patch) | |
tree | 8f7a19431e305aff3d73e7c9300c2accaf294e87 /lib/libc/thread | |
parent | 2717495d33a63467db8130f749e61927d7efafb9 (diff) |
If the init_routine used with pthread_once() is canceled, then we need to
unlock the mutex inside the pthread_once_t. Push a cleanup wrapper for that.
Diff from Scott Cheloha <scottcheloha@gmail.com>
ok mpi@
Diffstat (limited to 'lib/libc/thread')
-rw-r--r-- | lib/libc/thread/rthread_once.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/libc/thread/rthread_once.c b/lib/libc/thread/rthread_once.c index b8c6ba79161..014532e56c4 100644 --- a/lib/libc/thread/rthread_once.c +++ b/lib/libc/thread/rthread_once.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_once.c,v 1.1 2017/08/15 06:13:24 guenther Exp $ */ +/* $OpenBSD: rthread_once.c,v 1.2 2017/10/28 21:25:24 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -17,13 +17,23 @@ */ #include <pthread.h> +#include <stdlib.h> + +static void +mutex_unlock(void *arg) +{ + if (pthread_mutex_unlock(arg)) + abort(); +} int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { pthread_mutex_lock(&once_control->mutex); if (once_control->state == PTHREAD_NEEDS_INIT) { + pthread_cleanup_push(mutex_unlock, &once_control->mutex); init_routine(); + pthread_cleanup_pop(0); once_control->state = PTHREAD_DONE_INIT; } pthread_mutex_unlock(&once_control->mutex); |