diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-04-28 12:16:10 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-04-28 16:47:53 +0200 |
| commit | e36a776dc1070b4878b2b18538366fa369114f37 (patch) | |
| tree | e5050f5d70bb9644c6e47d6585216a70c95781af | |
| parent | 5bbeb0c6fc80b05f6ae92cf4fbc25f4fb41201cf (diff) | |
| download | PROJ-e36a776dc1070b4878b2b18538366fa369114f37.tar.gz PROJ-e36a776dc1070b4878b2b18538366fa369114f37.zip | |
Implement thread-safe creation of proj mutex (fixes #954)
| -rw-r--r-- | src/pj_mutex.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/src/pj_mutex.c b/src/pj_mutex.c index e734981f..80898a88 100644 --- a/src/pj_mutex.c +++ b/src/pj_mutex.c @@ -100,39 +100,40 @@ void pj_cleanup_lock() #include "pthread.h" -static pthread_mutex_t precreated_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t core_lock; -static int core_lock_created = 0; /************************************************************************/ -/* pj_acquire_lock() */ -/* */ -/* Acquire the PROJ.4 lock. */ +/* pj_create_lock() */ /************************************************************************/ -void pj_acquire_lock() +static void pj_create_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); + /* + ** 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); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); #else - pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); #endif - pthread_mutex_init(&core_lock, &mutex_attr); - core_lock_created = 1; + pthread_mutex_init(&core_lock, &mutex_attr); +} - pthread_mutex_unlock( &precreated_lock ); +/************************************************************************/ +/* pj_acquire_lock() */ +/* */ +/* Acquire the PROJ.4 lock. */ +/************************************************************************/ + +void pj_acquire_lock() +{ + 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"); } pthread_mutex_lock( &core_lock); @@ -170,6 +171,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 +196,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 } /************************************************************************/ |
