summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2003-05-29 20:54:00 +0000
committermtm <mtm@FreeBSD.org>2003-05-29 20:54:00 +0000
commit238a1fc561ef47ef23d773be262045b7cdeb2be1 (patch)
treede07205d57a8993805508957d2cb6c1a62e1b61f /lib/libthr
parentc9c9423632b4eeb62740ecfc805b6ef66cea77f9 (diff)
downloadFreeBSD-src-238a1fc561ef47ef23d773be262045b7cdeb2be1.zip
FreeBSD-src-238a1fc561ef47ef23d773be262045b7cdeb2be1.tar.gz
Use a static lock to ake sure pthread_cond_* functions called
from multiple threads don't initialze the same condition variable more than once. Explicitly compare cond pointers with PTHREAD_COND_INITIALIZER instead of NULL. Just because it happens to be defined as NULL is no reason to encourage the idea that people can call those functions with NULL pointers to a condition variable. Approved by: re/jhb
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_cond.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c
index 4ced82d..95e5589 100644
--- a/lib/libthr/thread/thr_cond.c
+++ b/lib/libthr/thread/thr_cond.c
@@ -38,8 +38,15 @@
#include "thr_private.h"
/*
+ * Proctect two different threads calling a pthread_cond_* function
+ * from accidentally initializing the condition variable twice.
+ */
+static spinlock_t static_cond_lock = _SPINLOCK_INITIALIZER;
+
+/*
* Prototypes
*/
+static inline int cond_init(pthread_cond_t *);
static pthread_t cond_queue_deq(pthread_cond_t);
static void cond_queue_remove(pthread_cond_t, pthread_t);
static void cond_queue_enq(pthread_cond_t, pthread_t);
@@ -202,7 +209,7 @@ cond_wait_common(pthread_cond_t * cond, pthread_mutex_t * mutex,
* If the condition variable is statically initialized, perform dynamic
* initialization.
*/
- if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0)
+ if (*cond == PTHREAD_COND_INITIALIZER && (rval = cond_init(cond)) != 0)
return (rval);
@@ -363,7 +370,7 @@ cond_signal(pthread_cond_t * cond, int broadcast)
* If the condition variable is statically initialized, perform dynamic
* initialization.
*/
- if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0)
+ if (*cond == PTHREAD_COND_INITIALIZER && (rval = cond_init(cond)) != 0)
return (rval);
COND_LOCK(*cond);
@@ -518,3 +525,14 @@ cond_queue_enq(pthread_cond_t cond, pthread_t pthread)
pthread->flags |= PTHREAD_FLAGS_IN_CONDQ;
pthread->data.cond = cond;
}
+
+static inline int
+cond_init(pthread_cond_t *cond)
+{
+ _SPINLOCK(&static_cond_lock);
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ return (_pthread_cond_init(cond, NULL));
+ _SPINUNLOCK(&static_cond_lock);
+ return (0);
+}
+
OpenPOWER on IntegriCloud