diff options
author | mtm <mtm@FreeBSD.org> | 2004-01-16 10:52:10 +0000 |
---|---|---|
committer | mtm <mtm@FreeBSD.org> | 2004-01-16 10:52:10 +0000 |
commit | e3c786562ff87850be855dfd169fb04002f8419a (patch) | |
tree | bb0ba3c680063e988a19dea0a54d0f940b679804 /lib/libthr | |
parent | 5af038f21added63f08bd826d3d748c044404156 (diff) | |
download | FreeBSD-src-e3c786562ff87850be855dfd169fb04002f8419a.zip FreeBSD-src-e3c786562ff87850be855dfd169fb04002f8419a.tar.gz |
Add an implementation of pthread_rwlock_timed{rd,wr}lock() to libthr with
attendant documentation.
Diffstat (limited to 'lib/libthr')
-rw-r--r-- | lib/libthr/thread/thr_rwlock.c | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c index f819a80..afd2fa5 100644 --- a/lib/libthr/thread/thr_rwlock.c +++ b/lib/libthr/thread/thr_rwlock.c @@ -40,13 +40,17 @@ __weak_reference(_pthread_rwlock_destroy, pthread_rwlock_destroy); __weak_reference(_pthread_rwlock_init, pthread_rwlock_init); __weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock); +__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); +__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); __weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); __weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); __weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); __weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); -static int rwlock_rdlock_common(pthread_rwlock_t *, int); -static int rwlock_wrlock_common(pthread_rwlock_t *, int); +static int rwlock_rdlock_common(pthread_rwlock_t *, int, + const struct timespec *); +static int rwlock_wrlock_common(pthread_rwlock_t *, int, + const struct timespec *); int _pthread_rwlock_destroy (pthread_rwlock_t *rwlock) @@ -116,7 +120,8 @@ out_mutex: * it is greater than 0 it will return immediately with EBUSY. */ static int -rwlock_rdlock_common(pthread_rwlock_t *rwlock, int nonblocking) +rwlock_rdlock_common(pthread_rwlock_t *rwlock, int nonblocking, + const struct timespec *timeout) { pthread_rwlock_t prwlock; int ret; @@ -124,6 +129,13 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, int nonblocking) if (rwlock == NULL || *rwlock == NULL) return(EINVAL); + /* + * Check for validity of the timeout parameter. + */ + if (timeout != NULL && + (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + return (EINVAL); + prwlock = *rwlock; /* grab the monitor lock */ @@ -143,7 +155,12 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, int nonblocking) return (EBUSY); } - ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock); + if (timeout == NULL) + ret = pthread_cond_wait(&prwlock->read_signal, + &prwlock->lock); + else + ret = pthread_cond_timedwait(&prwlock->read_signal, + &prwlock->lock, timeout); if (ret != 0 && ret != EINTR) { /* can't do a whole lot if this fails */ @@ -168,13 +185,20 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, int nonblocking) int _pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) { - return (rwlock_rdlock_common(rwlock, 0)); + return (rwlock_rdlock_common(rwlock, 0, NULL)); +} + +int +_pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, + const struct timespec *timeout) +{ + return (rwlock_rdlock_common(rwlock, 0, timeout)); } int _pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) { - return (rwlock_rdlock_common(rwlock, 1)); + return (rwlock_rdlock_common(rwlock, 1, NULL)); } int @@ -215,13 +239,20 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock) int _pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) { - return (rwlock_wrlock_common(rwlock, 0)); + return (rwlock_wrlock_common(rwlock, 0, NULL)); +} + +int +_pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, + const struct timespec *timeout) +{ + return (rwlock_wrlock_common(rwlock, 0, timeout)); } int _pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) { - return (rwlock_wrlock_common(rwlock, 1)); + return (rwlock_wrlock_common(rwlock, 1, NULL)); } /* @@ -229,7 +260,8 @@ _pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) * it is greater than 0 it will return immediately with EBUSY. */ static int -rwlock_wrlock_common(pthread_rwlock_t *rwlock, int nonblocking) +rwlock_wrlock_common(pthread_rwlock_t *rwlock, int nonblocking, + const struct timespec *timeout) { pthread_rwlock_t prwlock; int ret; @@ -237,6 +269,13 @@ rwlock_wrlock_common(pthread_rwlock_t *rwlock, int nonblocking) if (rwlock == NULL || *rwlock == NULL) return(EINVAL); + /* + * Check the timeout value for validity. + */ + if (timeout != NULL && + (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + return (EINVAL); + prwlock = *rwlock; /* grab the monitor lock */ @@ -251,8 +290,12 @@ rwlock_wrlock_common(pthread_rwlock_t *rwlock, int nonblocking) ++prwlock->blocked_writers; - ret = pthread_cond_wait(&prwlock->write_signal, - &prwlock->lock); + if (timeout == NULL) + ret = pthread_cond_wait(&prwlock->write_signal, + &prwlock->lock); + else + ret = pthread_cond_timedwait(&prwlock->write_signal, + &prwlock->lock, timeout); if (ret != 0 && ret != EINTR) { --prwlock->blocked_writers; |