aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-04-28 12:16:10 +0200
committerEven Rouault <even.rouault@spatialys.com>2018-04-28 16:47:53 +0200
commite36a776dc1070b4878b2b18538366fa369114f37 (patch)
treee5050f5d70bb9644c6e47d6585216a70c95781af
parent5bbeb0c6fc80b05f6ae92cf4fbc25f4fb41201cf (diff)
downloadPROJ-e36a776dc1070b4878b2b18538366fa369114f37.tar.gz
PROJ-e36a776dc1070b4878b2b18538366fa369114f37.zip
Implement thread-safe creation of proj mutex (fixes #954)
-rw-r--r--src/pj_mutex.c70
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
}
/************************************************************************/