diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2007-05-25 22:38:40 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2007-05-25 22:38:40 +0000 |
commit | 3e63d12de85bb03339039fd726ca30e5f9a849c2 (patch) | |
tree | 7b026359e462d95a854f89302808c4b26cb220f4 | |
parent | cf6b0419225c37055a1411362f764ffe042bfe5e (diff) |
protect against races while initializing static mutexes. okay marc@ tedu@
-rw-r--r-- | lib/librthread/rthread_sync.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c index 47d8ccda1fa..28706b6181d 100644 --- a/lib/librthread/rthread_sync.c +++ b/lib/librthread/rthread_sync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_sync.c,v 1.16 2006/01/05 04:06:48 marc Exp $ */ +/* $OpenBSD: rthread_sync.c,v 1.17 2007/05/25 22:38:39 kurt Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -37,6 +37,7 @@ #include "rthread.h" +static _spinlock_lock_t static_init_lock = _SPINLOCK_UNLOCKED; /* * Internal implementation of semaphores @@ -252,13 +253,19 @@ pthread_mutex_destroy(pthread_mutex_t *mutexp) static int _rthread_mutex_lock(pthread_mutex_t *mutexp, int trywait) { - pthread_mutex_t mutex = *mutexp; + pthread_mutex_t mutex; pthread_t thread = pthread_self(); - - if (!mutex) { - pthread_mutex_init(mutexp, NULL); - mutex = *mutexp; + int ret = 0; + + if (*mutexp == NULL) { + _spinlock(&static_init_lock); + if (*mutexp == NULL) + ret = pthread_mutex_init(mutexp, NULL); + _spinunlock(&static_init_lock); + if (ret != 0) + return (EINVAL); } + mutex = *mutexp; if (mutex->owner == thread) { if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { mutex->count++; |