aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2018-04-30 23:20:32 +0200
committerGitHub <noreply@github.com>2018-04-30 23:20:32 +0200
commit2fdbffca6c61687dc064e92d5a7fedc53ebb4744 (patch)
treeed9b6348518a6c6e0a178f83c02b0a79cab91c81 /src
parent2905808710c2450ec162c3052cd969936916fc57 (diff)
parent565cceda9bd8970dc76fd6001b7e09ec48267126 (diff)
downloadPROJ-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.c78
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
}
/************************************************************************/