diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2012-04-13 12:39:29 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2012-04-13 12:39:29 +0000 |
commit | 28e13e25d7be4da391c39ddc355060d5c010dcf0 (patch) | |
tree | a351a74df4298b4345505d2d10c2bcef0272de8d /lib/librthread | |
parent | c62d3c7016e5247f93b7618d75404841de76d85c (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.c | 38 |
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); |