summaryrefslogtreecommitdiff
path: root/lib/librthread
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2012-04-13 12:39:29 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2012-04-13 12:39:29 +0000
commit28e13e25d7be4da391c39ddc355060d5c010dcf0 (patch)
treea351a74df4298b4345505d2d10c2bcef0272de8d /lib/librthread
parentc62d3c7016e5247f93b7618d75404841de76d85c (diff)
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')
-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);