aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/ecpg/ecpglib/misc.c37
-rw-r--r--src/interfaces/ecpg/include/ecpg-pthread-win32.h22
-rw-r--r--src/interfaces/libpq/fe-connect.c16
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c20
-rw-r--r--src/interfaces/libpq/pthread-win32.c26
-rw-r--r--src/port/pthread-win32.h11
6 files changed, 63 insertions, 69 deletions
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 7f75e18733e..065cb3e696d 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -453,17 +453,38 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
#ifdef WIN32
#ifdef ENABLE_THREAD_SAFETY
-void
-win32_pthread_mutex(volatile pthread_mutex_t *mutex)
+int
+pthread_mutex_init(pthread_mutex_t *mp, void *attr)
+{
+ mp->initstate = 0;
+ return 0;
+}
+
+int
+pthread_mutex_lock(pthread_mutex_t *mp)
{
- if (mutex->handle == NULL)
+ /* Initialize the csection if not already done */
+ if (mp->initstate != 1)
{
- while (InterlockedExchange((LONG *) &mutex->initlock, 1) == 1)
- Sleep(0);
- if (mutex->handle == NULL)
- mutex->handle = CreateMutex(NULL, FALSE, NULL);
- InterlockedExchange((LONG *) &mutex->initlock, 0);
+ LONG istate;
+
+ while ((istate = InterlockedExchange(&mp->initstate, 2)) == 2)
+ Sleep(0); /* wait, another thread is doing this */
+ if (istate != 1)
+ InitializeCriticalSection(&mp->csection);
+ InterlockedExchange(&mp->initstate, 1);
}
+ EnterCriticalSection(&mp->csection);
+ return 0;
+}
+
+int
+pthread_mutex_unlock(pthread_mutex_t *mp)
+{
+ if (mp->initstate != 1)
+ return EINVAL;
+ LeaveCriticalSection(&mp->csection);
+ return 0;
}
static pthread_mutex_t win32_pthread_once_lock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 33c897b633c..2782e49d4cd 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -14,28 +14,22 @@
typedef struct pthread_mutex_t
{
- HANDLE handle;
- LONG initlock;
+ /* initstate = 0: not initialized; 1: init done; 2: init in progress */
+ LONG initstate;
+ CRITICAL_SECTION csection;
} pthread_mutex_t;
typedef DWORD pthread_key_t;
typedef bool pthread_once_t;
-#define PTHREAD_MUTEX_INITIALIZER { NULL, 0 }
+#define PTHREAD_MUTEX_INITIALIZER { 0 }
#define PTHREAD_ONCE_INIT false
-void win32_pthread_mutex(volatile pthread_mutex_t *mutex);
-void win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
+int pthread_mutex_init(pthread_mutex_t *, void *attr);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
-#define pthread_mutex_lock(mutex) \
- do { \
- if ((mutex)->handle == NULL) \
- win32_pthread_mutex((mutex)); \
- WaitForSingleObject((mutex)->handle, INFINITE); \
- } while(0)
-
-#define pthread_mutex_unlock(mutex) \
- ReleaseMutex((mutex)->handle)
+void win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void));
#define pthread_getspecific(key) \
TlsGetValue((key))
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a8584d2c684..6bce6f647bd 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -7785,24 +7785,8 @@ static void
default_threadlock(int acquire)
{
#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
-#else
- static pthread_mutex_t singlethread_lock = NULL;
- static long mutex_initlock = 0;
- if (singlethread_lock == NULL)
- {
- while (InterlockedExchange(&mutex_initlock, 1) == 1)
- /* loop, another thread own the lock */ ;
- if (singlethread_lock == NULL)
- {
- if (pthread_mutex_init(&singlethread_lock, NULL))
- Assert(false);
- }
- InterlockedExchange(&mutex_initlock, 0);
- }
-#endif
if (acquire)
{
if (pthread_mutex_lock(&singlethread_lock))
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 25569e6d113..82360b0e29b 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -94,12 +94,7 @@ static bool ssl_lib_initialized = false;
#ifdef ENABLE_THREAD_SAFETY
static long crypto_open_connections = 0;
-#ifndef WIN32
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
-#else
-static pthread_mutex_t ssl_config_mutex = NULL;
-static long win32_ssl_create_mutex = 0;
-#endif
#endif /* ENABLE_THREAD_SAFETY */
static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
@@ -783,20 +778,6 @@ int
pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
{
#ifdef ENABLE_THREAD_SAFETY
-#ifdef WIN32
- /* Also see similar code in fe-connect.c, default_threadlock() */
- if (ssl_config_mutex == NULL)
- {
- while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
- /* loop, another thread own the lock */ ;
- if (ssl_config_mutex == NULL)
- {
- if (pthread_mutex_init(&ssl_config_mutex, NULL))
- return -1;
- }
- InterlockedExchange(&win32_ssl_create_mutex, 0);
- }
-#endif
if (pthread_mutex_lock(&ssl_config_mutex))
return -1;
@@ -887,7 +868,6 @@ static void
destroy_ssl_system(void)
{
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
- /* Mutex is created in pgtls_init() */
if (pthread_mutex_lock(&ssl_config_mutex))
return;
diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c
index 8e656373876..bf8d76b5256 100644
--- a/src/interfaces/libpq/pthread-win32.c
+++ b/src/interfaces/libpq/pthread-win32.c
@@ -34,27 +34,33 @@ pthread_getspecific(pthread_key_t key)
int
pthread_mutex_init(pthread_mutex_t *mp, void *attr)
{
- *mp = (CRITICAL_SECTION *) malloc(sizeof(CRITICAL_SECTION));
- if (!*mp)
- return 1;
- InitializeCriticalSection(*mp);
+ mp->initstate = 0;
return 0;
}
int
pthread_mutex_lock(pthread_mutex_t *mp)
{
- if (!*mp)
- return 1;
- EnterCriticalSection(*mp);
+ /* Initialize the csection if not already done */
+ if (mp->initstate != 1)
+ {
+ LONG istate;
+
+ while ((istate = InterlockedExchange(&mp->initstate, 2)) == 2)
+ Sleep(0); /* wait, another thread is doing this */
+ if (istate != 1)
+ InitializeCriticalSection(&mp->csection);
+ InterlockedExchange(&mp->initstate, 1);
+ }
+ EnterCriticalSection(&mp->csection);
return 0;
}
int
pthread_mutex_unlock(pthread_mutex_t *mp)
{
- if (!*mp)
- return 1;
- LeaveCriticalSection(*mp);
+ if (mp->initstate != 1)
+ return EINVAL;
+ LeaveCriticalSection(&mp->csection);
return 0;
}
diff --git a/src/port/pthread-win32.h b/src/port/pthread-win32.h
index 97ccc17a126..5f33269057c 100644
--- a/src/port/pthread-win32.h
+++ b/src/port/pthread-win32.h
@@ -5,7 +5,16 @@
#define __PTHREAD_H
typedef ULONG pthread_key_t;
-typedef CRITICAL_SECTION *pthread_mutex_t;
+
+typedef struct pthread_mutex_t
+{
+ /* initstate = 0: not initialized; 1: init done; 2: init in progress */
+ LONG initstate;
+ CRITICAL_SECTION csection;
+} pthread_mutex_t;
+
+#define PTHREAD_MUTEX_INITIALIZER { 0 }
+
typedef int pthread_once_t;
DWORD pthread_self(void);