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
This commit is contained in:
Alexander Langer 1998-08-02 17:04:25 +00:00
parent bb6ae0a4a9
commit 27aa2e8958
3 changed files with 63 additions and 12 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);