diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c index 2b78caeaf5..58fff10697 100644 --- a/src/interfaces/ecpg/ecpglib/misc.c +++ b/src/interfaces/ecpg/ecpglib/misc.c @@ -407,17 +407,38 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr) #ifdef WIN32 -void -win32_pthread_mutex(volatile pthread_mutex_t *mutex) +int +pthread_mutex_init(pthread_mutex_t *mp, void *attr) { - if (mutex->handle == NULL) + mp->initstate = 0; + return 0; +} + +int +pthread_mutex_lock(pthread_mutex_t *mp) +{ + /* 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 8252a17809..7b6ba46b34 100644 --- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h +++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h @@ -12,29 +12,23 @@ 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); +int pthread_mutex_init(pthread_mutex_t *, void *attr); +int pthread_mutex_lock(pthread_mutex_t *); +int pthread_mutex_unlock(pthread_mutex_t *); + void win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void)); -#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) - #define pthread_getspecific(key) \ TlsGetValue((key)) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 64c0b628b3..d4e10a0c4f 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7426,24 +7426,8 @@ error: static void default_threadlock(int acquire) { -#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 6bc216956d..8110882262 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -91,12 +91,7 @@ static bool ssl_lib_initialized = false; 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 static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL; static int ssl_protocol_version_to_openssl(const char *protocol); @@ -773,20 +768,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line) int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto) { -#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; @@ -874,7 +855,6 @@ static void destroy_ssl_system(void) { #if 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 e607bee89a..b40872898d 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 97ccc17a12..5f33269057 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);