summaryrefslogtreecommitdiffstats
path: root/lib/libc_r
diff options
context:
space:
mode:
authoralex <alex@FreeBSD.org>1998-08-02 17:04:25 +0000
committeralex <alex@FreeBSD.org>1998-08-02 17:04:25 +0000
commita9c05a1ce9c647def2fa3209aa8b08d065e9f3c6 (patch)
tree8699b2e19a6295c89281abd86844b684970908fc /lib/libc_r
parent1d56e79a13576df16cca10607ab99daa27920cd2 (diff)
downloadFreeBSD-src-a9c05a1ce9c647def2fa3209aa8b08d065e9f3c6.zip
FreeBSD-src-a9c05a1ce9c647def2fa3209aa8b08d065e9f3c6.tar.gz
Fixed a race condition during the first lock/trylock of a statically
initialized mutex. Statically initialized mutexes are actually initialized at first use (pthread_mutex_lock/pthread_mutex_trylock). To prevent concurrent initialization by multiple threads, all static initializations are now serialized by a spinlock. Reviewed by: jb
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/uthread/uthread_mutex.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c
index 95c2083..e765a6b 100644
--- a/lib/libc_r/uthread/uthread_mutex.c
+++ b/lib/libc_r/uthread/uthread_mutex.c
@@ -37,6 +37,8 @@
#include <pthread.h>
#include "pthread_private.h"
+static spinlock_t static_init_lock = _SPINLOCK_INITIALIZER;
+
int
pthread_mutex_init(pthread_mutex_t * mutex,
const pthread_mutexattr_t * mutex_attr)
@@ -137,6 +139,23 @@ pthread_mutex_destroy(pthread_mutex_t * mutex)
return (ret);
}
+static int
+init_static (pthread_mutex_t *mutex)
+{
+ int ret;
+
+ _SPINLOCK(&static_init_lock);
+
+ if ( *mutex == NULL )
+ ret = pthread_mutex_init(mutex, NULL);
+ else
+ ret = 0;
+
+ _SPINUNLOCK(&static_init_lock);
+
+ return(ret);
+}
+
int
pthread_mutex_trylock(pthread_mutex_t * mutex)
{
@@ -149,8 +168,7 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)
* If the mutex is statically initialized, perform the dynamic
* initialization:
*/
- else if (*mutex != NULL ||
- (ret = pthread_mutex_init(mutex,NULL)) == 0) {
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
/* Lock the mutex structure: */
_SPINLOCK(&(*mutex)->lock);
@@ -216,8 +234,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex)
* If the mutex is statically initialized, perform the dynamic
* initialization:
*/
- else if (*mutex != NULL ||
- (ret = pthread_mutex_init(mutex,NULL)) == 0) {
+ else if (*mutex != NULL || (ret = init_static(mutex)) == 0) {
/* Lock the mutex structure: */
_SPINLOCK(&(*mutex)->lock);
OpenPOWER on IntegriCloud