diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-04-30 23:20:32 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-30 23:20:32 +0200 |
| commit | 2fdbffca6c61687dc064e92d5a7fedc53ebb4744 (patch) | |
| tree | ed9b6348518a6c6e0a178f83c02b0a79cab91c81 /src | |
| parent | 2905808710c2450ec162c3052cd969936916fc57 (diff) | |
| parent | 565cceda9bd8970dc76fd6001b7e09ec48267126 (diff) | |
| download | PROJ-2fdbffca6c61687dc064e92d5a7fedc53ebb4744.tar.gz PROJ-2fdbffca6c61687dc064e92d5a7fedc53ebb4744.zip | |
Merge pull request #958 from rouault/safe_creation_of_pj_lock
Implement thread-safe creation of proj mutex (fixes #954)
Diffstat (limited to 'src')
| -rw-r--r-- | src/pj_mutex.c | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/src/pj_mutex.c b/src/pj_mutex.c index e734981f..ba1b2def 100644 --- a/src/pj_mutex.c +++ b/src/pj_mutex.c @@ -33,6 +33,8 @@ #define _XOPEN_SOURCE 500 #endif +/* For PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */ +#define _GNU_SOURCE #ifndef _WIN32 #include "proj_config.h" @@ -100,9 +102,32 @@ void pj_cleanup_lock() #include "pthread.h" -static pthread_mutex_t precreated_lock = PTHREAD_MUTEX_INITIALIZER; +#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +static pthread_mutex_t core_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#else static pthread_mutex_t core_lock; -static int core_lock_created = 0; + +/************************************************************************/ +/* pj_create_lock() */ +/************************************************************************/ + +static void pj_create_lock() +{ + /* + ** We need to ensure the core mutex is created in recursive mode + */ + pthread_mutexattr_t mutex_attr; + + pthread_mutexattr_init(&mutex_attr); +#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); +#else + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); +#endif + pthread_mutex_init(&core_lock, &mutex_attr); +} + +#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */ /************************************************************************/ /* pj_acquire_lock() */ @@ -112,28 +137,14 @@ static int core_lock_created = 0; void pj_acquire_lock() { - if (!core_lock_created) { - /* - ** We need to ensure the core mutex is created in recursive mode - ** and there is no portable way of doing that using automatic - ** initialization so we have precreated_lock only for the purpose - ** of protecting the creation of the core lock. - */ - pthread_mutexattr_t mutex_attr; - - pthread_mutex_lock( &precreated_lock); - - pthread_mutexattr_init(&mutex_attr); -#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE - pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); -#else - pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); -#endif - pthread_mutex_init(&core_lock, &mutex_attr); - core_lock_created = 1; - pthread_mutex_unlock( &precreated_lock ); +#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + static pthread_once_t sOnceKey = PTHREAD_ONCE_INIT; + if( pthread_once(&sOnceKey, pj_create_lock) != 0 ) + { + fprintf(stderr, "pthread_once() failed in pj_acquire_lock().\n"); } +#endif pthread_mutex_lock( &core_lock); } @@ -170,6 +181,24 @@ void pj_cleanup_lock() static HANDLE mutex_lock = NULL; +#if _WIN32_WINNT >= 0x0600 + +/************************************************************************/ +/* pj_create_lock() */ +/************************************************************************/ + +static BOOL CALLBACK pj_create_lock(PINIT_ONCE InitOnce, + PVOID Parameter, + PVOID *Context) +{ + (void)InitOnce; + (void)Parameter; + (void)Context; + mutex_lock = CreateMutex( NULL, FALSE, NULL ); + return TRUE; +} +#endif + /************************************************************************/ /* pj_init_lock() */ /************************************************************************/ @@ -177,8 +206,13 @@ static HANDLE mutex_lock = NULL; static void pj_init_lock() { +#if _WIN32_WINNT >= 0x0600 + static INIT_ONCE sInitOnce = INIT_ONCE_STATIC_INIT; + InitOnceExecuteOnce( &sInitOnce, pj_create_lock, NULL, NULL ); +#else if( mutex_lock == NULL ) mutex_lock = CreateMutex( NULL, FALSE, NULL ); +#endif } /************************************************************************/ |
