From 9a6ba833a853efbae2ec0b6e37ede4f359450132 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= <eXpl0it3r@my-gate.net>
Date: Sun, 11 Oct 2026 12:29:44 +0200
Subject: [PATCH v1] Rename the Windows pthread emulation functions in libpq
 and ecpglib

libpq and ecpglib each come with a small pthread emulation on Windows,
whose functions have the same names as the real ones, e.g.
pthread_mutex_lock. When an application links the static libraries and
also uses a real pthreads library like PThreads4W, the linker finds the
same symbols twice and fails with LNK2005. Depending on the link order,
libpq's and ecpglib's emulations also end up clashing with each other.

Rename the functions with macros in the two emulation headers, which are
included by the definitions and by every caller. None of the functions
are exported from the DLLs, so the ABI stays the same.
---
 src/interfaces/ecpg/include/ecpg-pthread-win32.h |  9 +++++++++
 src/port/pthread-win32.h                         | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
index 7b6ba46..c7649f8 100644
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
@@ -23,6 +23,15 @@ typedef bool pthread_once_t;
 #define PTHREAD_MUTEX_INITIALIZER	{ 0 }
 #define PTHREAD_ONCE_INIT			false
 
+/*
+ * Rename the emulation functions, so they don't clash with libpq's or with a
+ * real pthreads library, like PThreads4W, that ends up in the same static
+ * link.
+ */
+#define pthread_mutex_init ecpg_pthread_mutex_init
+#define pthread_mutex_lock ecpg_pthread_mutex_lock
+#define pthread_mutex_unlock ecpg_pthread_mutex_unlock
+
 int			pthread_mutex_init(pthread_mutex_t *, void *attr);
 int			pthread_mutex_lock(pthread_mutex_t *);
 int			pthread_mutex_unlock(pthread_mutex_t *);
diff --git a/src/port/pthread-win32.h b/src/port/pthread-win32.h
index 5f33269..96648e5 100644
--- a/src/port/pthread-win32.h
+++ b/src/port/pthread-win32.h
@@ -4,6 +4,17 @@
 #ifndef __PTHREAD_H
 #define __PTHREAD_H
 
+/*
+ * Rename the emulation functions, so they don't clash with a real pthreads
+ * library on Windows, like PThreads4W, that ends up in the same static link.
+ */
+#define pthread_self pq_pthread_self
+#define pthread_setspecific pq_pthread_setspecific
+#define pthread_getspecific pq_pthread_getspecific
+#define pthread_mutex_init pq_pthread_mutex_init
+#define pthread_mutex_lock pq_pthread_mutex_lock
+#define pthread_mutex_unlock pq_pthread_mutex_unlock
+
 typedef ULONG pthread_key_t;
 
 typedef struct pthread_mutex_t
-- 
2.55.0.windows.5

