From e36a776dc1070b4878b2b18538366fa369114f37 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Apr 2018 12:16:10 +0200 Subject: Implement thread-safe creation of proj mutex (fixes #954) --- src/pj_mutex.c | 70 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 23 deletions(-) (limited to 'src') 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 } /************************************************************************/ -- cgit v1.2.3 From 565cceda9bd8970dc76fd6001b7e09ec48267126 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Apr 2018 12:33:21 +0200 Subject: pj_mutex.c: use PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP when available --- src/pj_mutex.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/pj_mutex.c b/src/pj_mutex.c index 80898a88..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,6 +102,9 @@ void pj_cleanup_lock() #include "pthread.h" +#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +static pthread_mutex_t core_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#else static pthread_mutex_t core_lock; /************************************************************************/ @@ -122,6 +127,8 @@ static void pj_create_lock() pthread_mutex_init(&core_lock, &mutex_attr); } +#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */ + /************************************************************************/ /* pj_acquire_lock() */ /* */ @@ -130,11 +137,14 @@ static void pj_create_lock() void pj_acquire_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); } -- cgit v1.2.3