summaryrefslogtreecommitdiffstats
path: root/lib/librthread/rthread_sync.c
diff options
context:
space:
mode:
authorkurt <kurt@openbsd.org>2012-04-13 12:39:28 +0000
committerkurt <kurt@openbsd.org>2012-04-13 12:39:28 +0000
commitd7c0fb2a75e423964564603b9cf2944e32ea56c1 (patch)
tree2aa739b6fd17529415d3c439607f1d754be72e63 /lib/librthread/rthread_sync.c
parentDon't assume that the new conffd is a unset in the fd_set, it could be a (diff)
downloadwireguard-openbsd-d7c0fb2a75e423964564603b9cf2944e32ea56c1.tar.xz
wireguard-openbsd-d7c0fb2a75e423964564603b9cf2944e32ea56c1.zip
Per POSIX, PTHREAD_MUTEX_NORMAL type mutexes have undefined behavior for
certain conditions. In the case of unlocking an unlocked mutex we will allow that to succeed, all other undefined behaviors will result in an immediate abort(). okay guenther@
Diffstat (limited to 'lib/librthread/rthread_sync.c')
-rw-r--r--lib/librthread/rthread_sync.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c
index c5d74f131c6..a050ee60e6c 100644
--- a/lib/librthread/rthread_sync.c
+++ b/lib/librthread/rthread_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_sync.c,v 1.33 2012/02/28 02:41:56 guenther Exp $ */
+/* $OpenBSD: rthread_sync.c,v 1.34 2012/04/13 12:39:28 kurt Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* Copyright (c) 2012 Philip Guenther <guenther@openbsd.org>
@@ -192,8 +192,23 @@ pthread_mutex_unlock(pthread_mutex_t *mutexp)
return (EPERM);
#endif
- if (mutex->owner != self)
- return (EPERM);
+ if (mutex->owner != self) {
+ if (mutex->type == PTHREAD_MUTEX_ERRORCHECK ||
+ mutex->type == PTHREAD_MUTEX_RECURSIVE)
+ return (EPERM);
+ else {
+ /*
+ * For mutex type NORMAL our undefined behavior for
+ * unlocking an unlocked mutex is to succeed without
+ * error. All other undefined behaviors are to
+ * abort() immediately.
+ */
+ if (mutex->owner == NULL)
+ return (0);
+ else
+ abort();
+ }
+ }
if (--mutex->count == 0) {
pthread_t next;
@@ -278,8 +293,13 @@ pthread_cond_timedwait(pthread_cond_t *condp, pthread_mutex_t *mutexp,
return (EPERM);
#endif
- if (mutex->owner != self)
- return (EPERM);
+ if (mutex->owner != self) {
+ if (mutex->type == PTHREAD_MUTEX_ERRORCHECK)
+ return (EPERM);
+ else
+ abort();
+ }
+
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
abstime->tv_nsec >= 1000000000)
return (EINVAL);
@@ -422,8 +442,12 @@ pthread_cond_wait(pthread_cond_t *condp, pthread_mutex_t *mutexp)
return (EPERM);
#endif
- if (mutex->owner != self)
- return (EPERM);
+ if (mutex->owner != self) {
+ if (mutex->type == PTHREAD_MUTEX_ERRORCHECK)
+ return (EPERM);
+ else
+ abort();
+ }
_enter_delayed_cancel(self);