From af70d578257735b8a2c44771969e04f8cb2eb217 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sat, 19 Jun 2004 04:22:17 +0000
Subject: [PATCH] Enable thread safety for win32.mak build of PostgreSQL.

Andreas Pflug
---
 src/interfaces/libpq/fe-connect.c    | 12 +++++++-
 src/interfaces/libpq/fe-secure.c     | 14 +++++++--
 src/interfaces/libpq/pthread-win32.c | 44 ++++++++++++++++++++++++++++
 src/interfaces/libpq/pthread.h.win32 | 17 +++++++++++
 src/interfaces/libpq/win32.mak       | 13 +++++---
 5 files changed, 92 insertions(+), 8 deletions(-)
 create mode 100644 src/interfaces/libpq/pthread-win32.c
 create mode 100644 src/interfaces/libpq/pthread.h.win32

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 720c47fb86b..c323c45fc6f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.274 2004/06/10 22:26:24 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.275 2004/06/19 04:22:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -882,10 +882,12 @@ connectDBStart(PGconn *conn)
 	const char *node = NULL;
 	int			ret;
 #ifdef ENABLE_THREAD_SAFETY
+#ifndef WIN32
 	static pthread_once_t check_sigpipe_once = PTHREAD_ONCE_INIT;
 
 	/* Check only on first connection request */
 	pthread_once(&check_sigpipe_once, check_sigpipe_handler);
+#endif
 #endif
 
 	if (!conn)
@@ -3183,11 +3185,19 @@ PQinitSSL(int do_init)
 }
 
 static pgthreadlock_t default_threadlock;
+
 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;
+        static long mutex_initialized = 0;
+        if (!InterlockedExchange(&mutex_initialized, 1L))
+                pthread_mutex_init(&singlethread_lock, NULL);
+#endif
 	if (acquire)
 		pthread_mutex_lock(&singlethread_lock);
 	else
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 673c6aad4d1..c827f940e25 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.41 2004/06/03 00:13:19 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.42 2004/06/19 04:22:17 momjian Exp $
  *
  * NOTES
  *	  The client *requires* a valid server certificate.  Since
@@ -864,8 +864,14 @@ static int
 init_ssl_system(PGconn *conn)
 {
 #ifdef ENABLE_THREAD_SAFETY
-static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
+#ifndef WIN32
+        static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+#else
+        static pthread_mutex_t init_mutex;
+        static long mutex_initialized = 0L;
+        if (!InterlockedExchange(&mutex_initialized, 1L))
+                pthread_mutex_init(&init_mutex, NULL);
+#endif
 	pthread_mutex_lock(&init_mutex);
 	
 	if (pq_initssllib && pq_lockarray == NULL) {
@@ -1171,6 +1177,7 @@ PQgetssl(PGconn *conn)
 
 
 #ifdef ENABLE_THREAD_SAFETY
+#ifndef WIN32
 /*
  *	Check SIGPIPE handler and perhaps install our own.
  */
@@ -1211,6 +1218,7 @@ sigpipe_handler_ignore_send(int signo)
 		exit(128 + SIGPIPE);	/* typical return value for SIG_DFL */
 }
 #endif
+#endif
  
 /*
  *	Indicates whether the current thread is in send()
diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c
new file mode 100644
index 00000000000..87546424df0
--- /dev/null
+++ b/src/interfaces/libpq/pthread-win32.c
@@ -0,0 +1,44 @@
+/*-------------------------------------------------------------------------
+*
+* pthread-win32.c
+*    partial pthread implementation for win32
+*
+* Copyright (c) 2004, PostgreSQL Global Development Group
+* IDENTIFICATION
+*   $PostgreSQL: pgsql/src/interfaces/libpq/pthread-win32.c,v 1.1 2004/06/19 04:22:17 momjian Exp $ 
+*
+*-------------------------------------------------------------------------
+*/
+
+
+#include "windows.h"
+#include "pthread.h"
+
+HANDLE pthread_self()
+{
+   return GetCurrentThread();
+}
+
+void pthread_setspecific(pthread_key_t key, void *val)
+{
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{
+    return NULL;
+}
+
+void pthread_mutex_init(pthread_mutex_t *mp, void *attr)
+{
+   *mp = CreateMutex(0, 0, 0);
+}
+
+void pthread_mutex_lock(pthread_mutex_t *mp)
+{
+   WaitForSingleObject(*mp, INFINITE);
+}
+
+void pthread_mutex_unlock(pthread_mutex_t *mp)
+{
+   ReleaseMutex(*mp);
+}
diff --git a/src/interfaces/libpq/pthread.h.win32 b/src/interfaces/libpq/pthread.h.win32
new file mode 100644
index 00000000000..5172cc3cafa
--- /dev/null
+++ b/src/interfaces/libpq/pthread.h.win32
@@ -0,0 +1,17 @@
+#ifndef __PTHREAD_H
+#define __PTHREAD_H
+
+typedef ULONG pthread_key_t;
+typedef HANDLE pthread_mutex_t;
+typedef int pthread_once_t;
+
+HANDLE pthread_self();
+
+void pthread_setspecific(pthread_key_t, void*);
+void* pthread_getspecific(pthread_key_t);
+
+void pthread_mutex_init(pthread_mutex_t *, void *attr);
+void pthread_mutex_lock(pthread_mutex_t*); // blocking
+void pthread_mutex_unlock(pthread_mutex_t*);
+
+#endif
diff --git a/src/interfaces/libpq/win32.mak b/src/interfaces/libpq/win32.mak
index 99e94fc6930..bb79041790d 100644
--- a/src/interfaces/libpq/win32.mak
+++ b/src/interfaces/libpq/win32.mak
@@ -4,7 +4,7 @@
 #        and a Win32 dynamic library libpq(d).dll with import library libpq(d)dll.lib
 # USE_SSL=1 will compile with OpenSSL
 # DEBUG=1 compiles with debugging symbols
-
+# ENABLE_THREAD_SAFETY=1 compiles with threading enabled
 
 !MESSAGE Building the Win32 static library...
 !MESSAGE
@@ -74,21 +74,25 @@ CLEAN :
 	-@erase "$(OUTDIR)\$(OUTFILENAME)dll.lib"
 	-@erase "$(INTDIR)\wchar.obj"
 	-@erase "$(INTDIR)\encnames.obj"
+	-@erase "$(INTDIR)\pthread-win32.obj"
 
 
 
-config: ..\..\include\pg_config.h pg_config_paths.h
+config: ..\..\include\pg_config.h pthread.h pg_config_paths.h
 
 ..\..\include\pg_config.h: ..\..\include\pg_config.h.win32
 	copy ..\..\include\pg_config.h.win32 ..\..\include\pg_config.h
 
+pthread.h: pthread.h.win32
+	copy pthread.h.win32 pthread.h
+
 pg_config_paths.h: win32.mak
 	echo #define SYSCONFDIR "" >pg_config_paths.h
 
 "$(OUTDIR)" :
     if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
 
-CPP_PROJ=/nologo /W3 /GX $(OPT) /I "..\..\include" /D "FRONTEND" $(DEBUGDEF) /D\
+CPP_PROJ=/nologo /W3 /GX $(OPT) /I "..\..\include" /I. /D "FRONTEND" $(DEBUGDEF) /D\
  "WIN32" /D "_WINDOWS" /Fp"$(INTDIR)\libpq.pch" /YX\
  /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c  /D "HAVE_VSNPRINTF" /D "HAVE_STRDUP"
 
@@ -127,7 +131,8 @@ LIB32_OBJS= \
 	"$(INTDIR)\fe-secure.obj" \
 	"$(INTDIR)\pqexpbuffer.obj" \
 	"$(INTDIR)\wchar.obj" \
-	"$(INTDIR)\encnames.obj"
+	"$(INTDIR)\encnames.obj" \
+	"$(INTDIR)\pthread-win32.obj"
 
 
 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libpq.res"
-- 
GitLab