diff options
author | mtm <mtm@FreeBSD.org> | 2003-05-29 20:54:00 +0000 |
---|---|---|
committer | mtm <mtm@FreeBSD.org> | 2003-05-29 20:54:00 +0000 |
commit | 238a1fc561ef47ef23d773be262045b7cdeb2be1 (patch) | |
tree | de07205d57a8993805508957d2cb6c1a62e1b61f /lib/libthr | |
parent | c9c9423632b4eeb62740ecfc805b6ef66cea77f9 (diff) | |
download | FreeBSD-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.c | 22 |
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); +} + |