aboutsummaryrefslogtreecommitdiff
path: root/lib/libc_r
diff options
context:
space:
mode:
authorAlexander Langer <alex@FreeBSD.org>1998-08-02 17:04:25 +0000
committerAlexander Langer <alex@FreeBSD.org>1998-08-02 17:04:25 +0000
commit27aa2e8958837ac373bb786a1f712492cb199451 (patch)
tree974d46c8e9648f1262c6a9a6e99a21792c406595 /lib/libc_r
parentbb6ae0a4a9ffb90a23f993da06e352d1af559243 (diff)
downloadsrc-27aa2e8958837ac373bb786a1f712492cb199451.tar.gz
src-27aa2e8958837ac373bb786a1f712492cb199451.zip
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
Notes
Notes: svn path=/head/; revision=38025
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 95c2083934b4..e765a6bc3616 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);