summaryrefslogtreecommitdiff
path: root/lib/librthread/rthread_sync.c
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2008-02-22 09:18:29 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2008-02-22 09:18:29 +0000
commit2797d267f96a5ae29c0b37eace0634f74dfa674a (patch)
treeafdb77cbb9e5468c9f98413ca77ab739b51ca7bc /lib/librthread/rthread_sync.c
parentfe7e070b23a04b6e2c0a66e72bce647c7e50b09d (diff)
fix rwlocks to work with the "initialized" form, from Philip Guenther
Diffstat (limited to 'lib/librthread/rthread_sync.c')
-rw-r--r--lib/librthread/rthread_sync.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c
index 29c561b7dee..6755852502f 100644
--- a/lib/librthread/rthread_sync.c
+++ b/lib/librthread/rthread_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_sync.c,v 1.18 2007/06/05 18:11:49 kurt Exp $ */
+/* $OpenBSD: rthread_sync.c,v 1.19 2008/02/22 09:18:28 tedu Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -157,7 +157,7 @@ sem_destroy(sem_t *semp)
return (EINVAL);
if ((*semp)->waitcount) {
#define MSG "sem_destroy on semaphore with waiters!\n"
- write(2, MSG, sizeof(MSG));
+ write(2, MSG, sizeof(MSG) - 1);
#undef MSG
return (EBUSY);
}
@@ -241,7 +241,7 @@ pthread_mutex_destroy(pthread_mutex_t *mutexp)
if ((*mutexp) && (*mutexp)->count) {
#define MSG "pthread_mutex_destroy on mutex with waiters!\n"
- write(2, MSG, sizeof(MSG));
+ write(2, MSG, sizeof(MSG) - 1);
#undef MSG
return (EBUSY);
}
@@ -502,16 +502,46 @@ pthread_rwlock_init(pthread_rwlock_t *lockp, const pthread_rwlockattr_t *attrp)
int
pthread_rwlock_destroy(pthread_rwlock_t *lockp)
{
+ if ((*lockp) && ((*lockp)->readers || (*lockp)->writer)) {
+#define MSG "pthread_rwlock_destroy on rwlock with waiters!\n"
+ write(2, MSG, sizeof(MSG) - 1);
+#undef MSG
+ return (EBUSY);
+ }
free(*lockp);
*lockp = NULL;
return (0);
}
+static int
+_rthread_rwlock_ensure_init(pthread_rwlock_t *lockp)
+{
+ int ret = 0;
+
+ /*
+ * If the rwlock is statically initialized, perform the dynamic
+ * initialization.
+ */
+ if (*lockp == NULL)
+ {
+ _spinlock(&static_init_lock);
+ if (*lockp == NULL)
+ ret = pthread_rwlock_init(lockp, NULL);
+ _spinunlock(&static_init_lock);
+ }
+ return (ret);
+}
+
+
int
pthread_rwlock_rdlock(pthread_rwlock_t *lockp)
{
pthread_rwlock_t lock;
+ int error;
+
+ if ((error = _rthread_rwlock_ensure_init(lockp)))
+ return (error);
lock = *lockp;
again:
@@ -531,6 +561,10 @@ int
pthread_rwlock_tryrdlock(pthread_rwlock_t *lockp)
{
pthread_rwlock_t lock;
+ int error;
+
+ if ((error = _rthread_rwlock_ensure_init(lockp)))
+ return (error);
lock = *lockp;
@@ -549,6 +583,10 @@ int
pthread_rwlock_wrlock(pthread_rwlock_t *lockp)
{
pthread_rwlock_t lock;
+ int error;
+
+ if ((error = _rthread_rwlock_ensure_init(lockp)))
+ return (error);
lock = *lockp;
@@ -570,6 +608,10 @@ int
pthread_rwlock_trywrlock(pthread_rwlock_t *lockp)
{
pthread_rwlock_t lock;
+ int error;
+
+ if ((error = _rthread_rwlock_ensure_init(lockp)))
+ return (error);
lock = *lockp;