diff options
author | 2017-10-28 21:25:24 +0000 | |
---|---|---|
committer | 2017-10-28 21:25:24 +0000 | |
commit | eb59ee9a45e0f19979fa0d4ef567f683d048aafb (patch) | |
tree | 94417ea3ed5157a9f8c47857b5098d12b6cade34 /lib/libc | |
parent | Change pthread_cleanup_{push,pop} to macros that store the cleanup info (diff) | |
download | wireguard-openbsd-eb59ee9a45e0f19979fa0d4ef567f683d048aafb.tar.xz wireguard-openbsd-eb59ee9a45e0f19979fa0d4ef567f683d048aafb.zip |
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')
-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); |