pthread_rwlock_unlock
- Allow callers to try and release an unheld rwlock. Just return EPERM as mandated by IEEE Std 1003.1. - Use pthread__atomic_swap_ptr() to set in the new lock value. At this point the lock word can't have changed. pthread__rwlock_wrlock, pthread__rwlock_rdlock: - Mask out the waiter bits in the lock word before checking to see if the current thread is about to lock against itself.
This commit is contained in:
parent
2d6848b0e4
commit
9212747aea
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pthread_rwlock2.c,v 1.3 2007/09/10 11:34:06 skrll Exp $ */
|
||||
/* $NetBSD: pthread_rwlock2.c,v 1.4 2007/09/21 16:21:54 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2006, 2007 The NetBSD Foundation, Inc.
|
||||
@ -37,10 +37,9 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: pthread_rwlock2.c,v 1.3 2007/09/10 11:34:06 skrll Exp $");
|
||||
__RCSID("$NetBSD: pthread_rwlock2.c,v 1.4 2007/09/21 16:21:54 ad Exp $");
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "pthread.h"
|
||||
@ -141,7 +140,7 @@ pthread__rwlock_rdlock(pthread_rwlock_t *ptr, const struct timespec *ts)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (owner == (uintptr_t)self)
|
||||
if ((owner & RW_THREAD) == (uintptr_t)self)
|
||||
return EDEADLK;
|
||||
|
||||
/*
|
||||
@ -254,7 +253,7 @@ pthread__rwlock_wrlock(pthread_rwlock_t *ptr, const struct timespec *ts)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (owner == (uintptr_t)self)
|
||||
if ((owner & RW_THREAD) == (uintptr_t)self)
|
||||
return EDEADLK;
|
||||
|
||||
/*
|
||||
@ -391,8 +390,9 @@ pthread_rwlock_unlock(pthread_rwlock_t *ptr)
|
||||
* the read-release and write-release path similar.
|
||||
*/
|
||||
owner = (uintptr_t)ptr->ptr_owner;
|
||||
pthread__error(EINVAL, "releasing unheld rwlock", owner != 0);
|
||||
|
||||
if (owner == 0) {
|
||||
return EPERM;
|
||||
}
|
||||
if ((owner & RW_WRITE_LOCKED) != 0) {
|
||||
decr = (uintptr_t)self | RW_WRITE_LOCKED;
|
||||
pthread__error(EPERM, "releasing rwlock held by another thread",
|
||||
@ -444,8 +444,8 @@ pthread_rwlock_unlock(pthread_rwlock_t *ptr)
|
||||
* Set in the new value. The lock becomes owned
|
||||
* by the writer that we are about to wake.
|
||||
*/
|
||||
while (!rw_cas(ptr, &owner, new))
|
||||
;
|
||||
(void)pthread__atomic_swap_ptr(&ptr->ptr_owner,
|
||||
(void *)new);
|
||||
|
||||
/* Wake the writer. */
|
||||
PTQ_REMOVE(&ptr->ptr_wblocked, thread, pt_sleep);
|
||||
@ -471,8 +471,8 @@ pthread_rwlock_unlock(pthread_rwlock_t *ptr)
|
||||
* Set in the new value. The lock becomes owned
|
||||
* by the readers that we are about to wake.
|
||||
*/
|
||||
while (!rw_cas(ptr, &owner, new))
|
||||
;
|
||||
(void)pthread__atomic_swap_ptr(&ptr->ptr_owner,
|
||||
(void *)new);
|
||||
|
||||
/* Wake up all sleeping readers. */
|
||||
ptr->ptr_nreaders = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user