summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2004-01-16 10:52:10 +0000
committermtm <mtm@FreeBSD.org>2004-01-16 10:52:10 +0000
commite3c786562ff87850be855dfd169fb04002f8419a (patch)
treebb0ba3c680063e988a19dea0a54d0f940b679804 /lib/libthr
parent5af038f21added63f08bd826d3d748c044404156 (diff)
downloadFreeBSD-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.c65
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;
OpenPOWER on IntegriCloud