0005-Replace-various-ad-hoc-abstractions-with-pg_threads..patch
text/x-patch
Filename: 0005-Replace-various-ad-hoc-abstractions-with-pg_threads..patch
Type: text/x-patch
Part: 4
Message:
Cleaning up threading code
Patch
Format: format-patch
Series: patch 0005
Subject: Replace various ad hoc abstractions with pg_threads.h.
| File | + | − |
|---|---|---|
| src/bin/pgbench/pgbench.c | 13 | 54 |
| src/interfaces/ecpg/ecpglib/connect.c | 22 | 21 |
| src/interfaces/ecpg/ecpglib/descriptor.c | 7 | 7 |
| src/interfaces/ecpg/ecpglib/memory.c | 7 | 7 |
| src/interfaces/ecpg/ecpglib/misc.c | 20 | 48 |
| src/interfaces/ecpg/ecpglib/sqlda.c | 0 | 1 |
| src/interfaces/ecpg/include/ecpg_config.h.in | 3 | 0 |
| src/interfaces/ecpg/include/ecpg-pthread-win32.h | 0 | 55 |
| src/interfaces/ecpg/include/meson.build | 1 | 0 |
| src/interfaces/ecpg/test/expected/thread-alloc.c | 22 | 51 |
| src/interfaces/ecpg/test/expected/thread-descriptor.c | 12 | 40 |
| src/interfaces/ecpg/test/expected/thread-prep.c | 36 | 63 |
| src/interfaces/ecpg/test/expected/thread-thread.c | 35 | 57 |
| src/interfaces/ecpg/test/expected/thread-thread_implicit.c | 35 | 57 |
| src/interfaces/ecpg/test/thread/alloc.pgc | 5 | 34 |
| src/interfaces/ecpg/test/thread/descriptor.pgc | 5 | 33 |
| src/interfaces/ecpg/test/thread/prep.pgc | 5 | 32 |
| src/interfaces/ecpg/test/thread/thread_implicit.pgc | 8 | 30 |
| src/interfaces/ecpg/test/thread/thread.pgc | 8 | 30 |
| src/interfaces/libpq/fe-connect.c | 14 | 25 |
| src/interfaces/libpq/fe-secure.c | 1 | 3 |
| src/interfaces/libpq/fe-secure-openssl.c | 24 | 39 |
| src/interfaces/libpq/libpq-int.h | 0 | 5 |
| src/interfaces/libpq/Makefile | 0 | 1 |
| src/interfaces/libpq/meson.build | 2 | 2 |
| src/interfaces/libpq/pthread-win32.c | 0 | 60 |
| src/port/pthread-win32.h | 0 | 22 |
| src/tools/pginclude/cpluspluscheck | 0 | 1 |
| src/tools/pginclude/headerscheck | 0 | 1 |
From 2e1281762b56bb6e62f71124611505e5e29e5627 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 9 Jun 2023 13:27:42 +1200
Subject: [PATCH 5/5] Replace various ad hoc abstractions with pg_threads.h.
Several places had their own macros and functions to abstract POSIX and
Windows threading APIs. Use the new centralized API instead.
---
src/bin/pgbench/pgbench.c | 67 +++----------
src/interfaces/ecpg/ecpglib/connect.c | 43 ++++----
src/interfaces/ecpg/ecpglib/descriptor.c | 14 +--
src/interfaces/ecpg/ecpglib/memory.c | 14 +--
src/interfaces/ecpg/ecpglib/misc.c | 68 ++++---------
src/interfaces/ecpg/ecpglib/sqlda.c | 1 -
.../ecpg/include/ecpg-pthread-win32.h | 55 -----------
src/interfaces/ecpg/include/ecpg_config.h.in | 3 +
src/interfaces/ecpg/include/meson.build | 1 +
.../ecpg/test/expected/thread-alloc.c | 73 +++++---------
.../ecpg/test/expected/thread-descriptor.c | 52 +++-------
.../ecpg/test/expected/thread-prep.c | 99 +++++++------------
.../ecpg/test/expected/thread-thread.c | 92 +++++++----------
.../test/expected/thread-thread_implicit.c | 92 +++++++----------
src/interfaces/ecpg/test/thread/alloc.pgc | 39 +-------
.../ecpg/test/thread/descriptor.pgc | 38 +------
src/interfaces/ecpg/test/thread/prep.pgc | 37 +------
src/interfaces/ecpg/test/thread/thread.pgc | 38 ++-----
.../ecpg/test/thread/thread_implicit.pgc | 38 ++-----
src/interfaces/libpq/Makefile | 1 -
src/interfaces/libpq/fe-connect.c | 39 +++-----
src/interfaces/libpq/fe-secure-openssl.c | 63 +++++-------
src/interfaces/libpq/fe-secure.c | 4 +-
src/interfaces/libpq/libpq-int.h | 5 -
src/interfaces/libpq/meson.build | 4 +-
src/interfaces/libpq/pthread-win32.c | 60 -----------
src/port/pthread-win32.h | 22 -----
src/tools/pginclude/cpluspluscheck | 1 -
src/tools/pginclude/headerscheck | 1 -
29 files changed, 285 insertions(+), 779 deletions(-)
delete mode 100644 src/interfaces/ecpg/include/ecpg-pthread-win32.h
delete mode 100644 src/interfaces/libpq/pthread-win32.c
delete mode 100644 src/port/pthread-win32.h
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 683fc5860f..57e3b5fb46 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -66,6 +66,7 @@
#include "libpq-fe.h"
#include "pgbench.h"
#include "port/pg_bitutils.h"
+#include "port/pg_threads.h"
#include "portability/instr_time.h"
/* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */
@@ -113,49 +114,6 @@ typedef struct socket_set
#endif /* POLL_USING_SELECT */
-/*
- * Multi-platform thread implementations
- */
-
-#ifdef WIN32
-/* Use Windows threads */
-#include <windows.h>
-#define GETERRNO() (_dosmaperr(GetLastError()), errno)
-#define THREAD_T HANDLE
-#define THREAD_FUNC_RETURN_TYPE unsigned
-#define THREAD_FUNC_RETURN return 0
-#define THREAD_FUNC_CC __stdcall
-#define THREAD_CREATE(handle, function, arg) \
- ((*(handle) = (HANDLE) _beginthreadex(NULL, 0, (function), (arg), 0, NULL)) == 0 ? errno : 0)
-#define THREAD_JOIN(handle) \
- (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0 ? \
- GETERRNO() : CloseHandle(handle) ? 0 : GETERRNO())
-#define THREAD_BARRIER_T SYNCHRONIZATION_BARRIER
-#define THREAD_BARRIER_INIT(barrier, n) \
- (InitializeSynchronizationBarrier((barrier), (n), 0) ? 0 : GETERRNO())
-#define THREAD_BARRIER_WAIT(barrier) \
- EnterSynchronizationBarrier((barrier), \
- SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
-#define THREAD_BARRIER_DESTROY(barrier)
-#else
-/* Use POSIX threads */
-#include "port/pg_pthread.h"
-#define THREAD_T pthread_t
-#define THREAD_FUNC_RETURN_TYPE void *
-#define THREAD_FUNC_RETURN return NULL
-#define THREAD_FUNC_CC
-#define THREAD_CREATE(handle, function, arg) \
- pthread_create((handle), NULL, (function), (arg))
-#define THREAD_JOIN(handle) \
- pthread_join((handle), NULL)
-#define THREAD_BARRIER_T pthread_barrier_t
-#define THREAD_BARRIER_INIT(barrier, n) \
- pthread_barrier_init((barrier), NULL, (n))
-#define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
-#define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
-#endif
-
-
/********************************************************************
* some configurable parameters */
@@ -477,7 +435,7 @@ typedef enum TStatus
static pg_prng_state base_random_sequence;
/* Synchronization barrier for start and connection */
-static THREAD_BARRIER_T barrier;
+static pg_thrd_barrier_t barrier;
/*
* Connection state machine states.
@@ -644,7 +602,7 @@ typedef struct
typedef struct
{
int tid; /* thread id */
- THREAD_T thread; /* thread handle */
+ pg_thrd_t thread; /* thread handle */
CState *state; /* array of CState */
int nstate; /* length of state[] */
@@ -825,7 +783,7 @@ static void doLog(TState *thread, CState *st,
static void processXactStats(TState *thread, CState *st, pg_time_usec_t *now,
bool skipped, StatsData *agg);
static void addScript(const ParsedScript *script);
-static THREAD_FUNC_RETURN_TYPE THREAD_FUNC_CC threadRun(void *arg);
+static int threadRun(void *arg);
static void finishCon(CState *st);
static void setalarm(int seconds);
static socket_set *alloc_socket_set(int count);
@@ -7218,7 +7176,7 @@ main(int argc, char **argv)
if (duration > 0)
setalarm(duration);
- errno = THREAD_BARRIER_INIT(&barrier, nthreads);
+ errno = pg_thrd_barrier_init(&barrier, nthreads);
if (errno != 0)
pg_fatal("could not initialize barrier: %m");
@@ -7228,7 +7186,7 @@ main(int argc, char **argv)
TState *thread = &threads[i];
thread->create_time = pg_time_now();
- errno = THREAD_CREATE(&thread->thread, threadRun, thread);
+ errno = pg_thrd_create(&thread->thread, threadRun, thread);
if (errno != 0)
pg_fatal("could not create thread: %m");
@@ -7251,7 +7209,7 @@ main(int argc, char **argv)
TState *thread = &threads[i];
if (i > 0)
- THREAD_JOIN(thread->thread);
+ pg_thrd_join(thread->thread, NULL);
for (int j = 0; j < thread->nstate; j++)
if (thread->state[j].state != CSTATE_FINISHED)
@@ -7291,7 +7249,7 @@ main(int argc, char **argv)
printResults(&stats, pg_time_now() - bench_start, conn_total_duration,
bench_start - start_time, latency_late);
- THREAD_BARRIER_DESTROY(&barrier);
+ pg_thrd_barrier_destroy(&barrier);
if (exit_code != 0)
pg_log_error("Run was aborted; the above results are incomplete.");
@@ -7299,7 +7257,7 @@ main(int argc, char **argv)
return exit_code;
}
-static THREAD_FUNC_RETURN_TYPE THREAD_FUNC_CC
+static int
threadRun(void *arg)
{
TState *thread = (TState *) arg;
@@ -7336,7 +7294,7 @@ threadRun(void *arg)
state[i].state = CSTATE_CHOOSE_SCRIPT;
/* READY */
- THREAD_BARRIER_WAIT(&barrier);
+ pg_thrd_barrier_wait(&barrier);
thread_start = pg_time_now();
thread->started_time = thread_start;
@@ -7360,7 +7318,7 @@ threadRun(void *arg)
}
/* GO */
- THREAD_BARRIER_WAIT(&barrier);
+ pg_thrd_barrier_wait(&barrier);
start = pg_time_now();
thread->bench_start = start;
@@ -7572,7 +7530,8 @@ done:
thread->logfile = NULL;
}
free_socket_set(sockets);
- THREAD_FUNC_RETURN;
+
+ return 0;
}
static void
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 8afb1f0a26..61ca9a0829 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -2,8 +2,8 @@
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
+#include "port/pg_threads.h"
-#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
@@ -14,22 +14,23 @@
locale_t ecpg_clocale = (locale_t) 0;
#endif
-static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t actual_connection_key;
-static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
+static pg_mtx_t connections_mutex;
+static pg_tss_t actual_connection_key;
+static pg_once_flag actual_connection_key_once = PG_ONCE_FLAG_INIT;
static struct connection *actual_connection = NULL;
static struct connection *all_connections = NULL;
static void
ecpg_actual_connection_init(void)
{
- pthread_key_create(&actual_connection_key, NULL);
+ pg_mtx_init(&connections_mutex, pg_mtx_plain);
+ pg_tss_create(&actual_connection_key, NULL);
}
void
ecpg_pthreads_init(void)
{
- pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
+ pg_call_once(&actual_connection_key_once, ecpg_actual_connection_init);
}
static struct connection *
@@ -41,7 +42,7 @@ ecpg_get_connection_nr(const char *connection_name)
{
ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
- ret = pthread_getspecific(actual_connection_key);
+ ret = pg_tss_get(actual_connection_key);
/*
* if no connection in TSD for this thread, get the global default
@@ -76,7 +77,7 @@ ecpg_get_connection(const char *connection_name)
{
ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
- ret = pthread_getspecific(actual_connection_key);
+ ret = pg_tss_get(actual_connection_key);
/*
* if no connection in TSD for this thread, get the global default
@@ -89,11 +90,11 @@ ecpg_get_connection(const char *connection_name)
}
else
{
- pthread_mutex_lock(&connections_mutex);
+ pg_mtx_lock(&connections_mutex);
ret = ecpg_get_connection_nr(connection_name);
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
}
return ret;
@@ -127,8 +128,8 @@ ecpg_finish(struct connection *act)
con->next = act->next;
}
- if (pthread_getspecific(actual_connection_key) == act)
- pthread_setspecific(actual_connection_key, all_connections);
+ if (pg_tss_get(actual_connection_key) == act)
+ pg_tss_set(actual_connection_key, all_connections);
if (actual_connection == act)
actual_connection = all_connections;
@@ -194,7 +195,7 @@ ECPGsetconn(int lineno, const char *connection_name)
if (!ecpg_init(con, connection_name, lineno))
return false;
- pthread_setspecific(actual_connection_key, con);
+ pg_tss_set(actual_connection_key, con);
return true;
}
@@ -481,7 +482,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
}
/* add connection to our list */
- pthread_mutex_lock(&connections_mutex);
+ pg_mtx_lock(&connections_mutex);
/*
* ... but first, make certain we have created ecpg_clocale. Rely on
@@ -493,7 +494,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
ecpg_clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
if (!ecpg_clocale)
{
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
if (host)
@@ -530,7 +531,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
this->next = all_connections;
all_connections = this;
- pthread_setspecific(actual_connection_key, all_connections);
+ pg_tss_set(actual_connection_key, all_connections);
actual_connection = all_connections;
ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
@@ -648,7 +649,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
ecpg_log("ECPGconnect: %s", errmsg);
ecpg_finish(this);
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
if (realname)
@@ -660,7 +661,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
if (realname)
ecpg_free(realname);
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
this->autocommit = autocommit;
@@ -682,7 +683,7 @@ ECPGdisconnect(int lineno, const char *connection_name)
return false;
}
- pthread_mutex_lock(&connections_mutex);
+ pg_mtx_lock(&connections_mutex);
if (strcmp(connection_name, "ALL") == 0)
{
@@ -701,14 +702,14 @@ ECPGdisconnect(int lineno, const char *connection_name)
if (!ecpg_init(con, connection_name, lineno))
{
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
return false;
}
else
ecpg_finish(con);
}
- pthread_mutex_unlock(&connections_mutex);
+ pg_mtx_unlock(&connections_mutex);
return true;
}
diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c
index ad279e245c..b57e065672 100644
--- a/src/interfaces/ecpg/ecpglib/descriptor.c
+++ b/src/interfaces/ecpg/ecpglib/descriptor.c
@@ -7,11 +7,11 @@
#include "postgres_fe.h"
#include "catalog/pg_type_d.h"
-#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
#include "ecpgtype.h"
+#include "port/pg_threads.h"
#include "sql3types.h"
#include "sqlca.h"
#include "sqlda.h"
@@ -19,8 +19,8 @@
static void descriptor_free(struct descriptor *desc);
/* We manage descriptors separately for each thread. */
-static pthread_key_t descriptor_key;
-static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
+static pg_tss_t descriptor_key;
+static pg_once_flag descriptor_once = PG_ONCE_FLAG_INIT;
static void descriptor_deallocate_all(struct descriptor *list);
@@ -33,20 +33,20 @@ descriptor_destructor(void *arg)
static void
descriptor_key_init(void)
{
- pthread_key_create(&descriptor_key, descriptor_destructor);
+ pg_tss_create(&descriptor_key, descriptor_destructor);
}
static struct descriptor *
get_descriptors(void)
{
- pthread_once(&descriptor_once, descriptor_key_init);
- return (struct descriptor *) pthread_getspecific(descriptor_key);
+ pg_call_once(&descriptor_once, descriptor_key_init);
+ return (struct descriptor *) pg_tss_get(descriptor_key);
}
static void
set_descriptors(struct descriptor *value)
{
- pthread_setspecific(descriptor_key, value);
+ pg_tss_set(descriptor_key, value);
}
/* old internal convenience function that might go away later */
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index a83637ac75..985f05087d 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -3,11 +3,11 @@
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
-#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
#include "ecpgtype.h"
+#include "port/pg_threads.h"
void
ecpg_free(void *ptr)
@@ -68,8 +68,8 @@ struct auto_mem
struct auto_mem *next;
};
-static pthread_key_t auto_mem_key;
-static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
+static pg_tss_t auto_mem_key;
+static pg_once_flag auto_mem_once = PG_ONCE_FLAG_INIT;
static void
auto_mem_destructor(void *arg)
@@ -81,20 +81,20 @@ auto_mem_destructor(void *arg)
static void
auto_mem_key_init(void)
{
- pthread_key_create(&auto_mem_key, auto_mem_destructor);
+ pg_tss_create(&auto_mem_key, auto_mem_destructor);
}
static struct auto_mem *
get_auto_allocs(void)
{
- pthread_once(&auto_mem_once, auto_mem_key_init);
- return (struct auto_mem *) pthread_getspecific(auto_mem_key);
+ pg_call_once(&auto_mem_once, auto_mem_key_init);
+ return (struct auto_mem *) pg_tss_get(auto_mem_key);
}
static void
set_auto_allocs(struct auto_mem *am)
{
- pthread_setspecific(auto_mem_key, am);
+ pg_tss_set(auto_mem_key, am);
}
char *
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 2b78caeaf5..b3d997e749 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -6,7 +6,6 @@
#include <limits.h>
#include <unistd.h>
-#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
@@ -16,6 +15,7 @@
#include "pgtypes_interval.h"
#include "pgtypes_numeric.h"
#include "pgtypes_timestamp.h"
+#include "port/pg_threads.h"
#include "sqlca.h"
#ifndef LONG_LONG_MIN
@@ -55,11 +55,10 @@ static struct sqlca_t sqlca_init =
}
};
-static pthread_key_t sqlca_key;
-static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-
-static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pg_tss_t sqlca_key;
+static pg_once_flag ecpg_once = PG_ONCE_FLAG_INIT;
+static pg_mtx_t debug_mutex;
+static pg_mtx_t debug_init_mutex;
static int simple_debug = 0;
static FILE *debugstream = NULL;
@@ -99,9 +98,11 @@ ecpg_sqlca_key_destructor(void *arg)
}
static void
-ecpg_sqlca_key_init(void)
+ecpg_init_once(void)
{
- pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
+ pg_tss_create(&sqlca_key, ecpg_sqlca_key_destructor);
+ pg_mtx_init(&debug_mutex, pg_mtx_plain);
+ pg_mtx_init(&debug_init_mutex, pg_mtx_plain);
}
struct sqlca_t *
@@ -109,16 +110,16 @@ ECPGget_sqlca(void)
{
struct sqlca_t *sqlca;
- pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
+ pg_call_once(&ecpg_once, ecpg_init_once);
- sqlca = pthread_getspecific(sqlca_key);
+ sqlca = pg_tss_get(sqlca_key);
if (sqlca == NULL)
{
sqlca = malloc(sizeof(struct sqlca_t));
if (sqlca == NULL)
return NULL;
ecpg_init_sqlca(sqlca);
- pthread_setspecific(sqlca_key, sqlca);
+ pg_tss_set(sqlca_key, sqlca);
}
return sqlca;
}
@@ -203,7 +204,9 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
void
ECPGdebug(int n, FILE *dbgs)
{
- pthread_mutex_lock(&debug_init_mutex);
+ pg_call_once(&ecpg_once, ecpg_init_once);
+
+ pg_mtx_lock(&debug_init_mutex);
if (n > 100)
{
@@ -217,7 +220,7 @@ ECPGdebug(int n, FILE *dbgs)
ecpg_log("ECPGdebug: set to %d\n", simple_debug);
- pthread_mutex_unlock(&debug_init_mutex);
+ pg_mtx_unlock(&debug_init_mutex);
}
void
@@ -249,7 +252,9 @@ ecpg_log(const char *format,...)
else
snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);
- pthread_mutex_lock(&debug_mutex);
+ pg_call_once(&ecpg_once, ecpg_init_once);
+
+ pg_mtx_lock(&debug_mutex);
va_start(ap, format);
vfprintf(debugstream, fmt, ap);
@@ -264,7 +269,7 @@ ecpg_log(const char *format,...)
fflush(debugstream);
- pthread_mutex_unlock(&debug_mutex);
+ pg_mtx_unlock(&debug_mutex);
free(fmt);
}
@@ -405,39 +410,6 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
return false;
}
-#ifdef WIN32
-
-void
-win32_pthread_mutex(volatile pthread_mutex_t *mutex)
-{
- if (mutex->handle == NULL)
- {
- while (InterlockedExchange((LONG *) &mutex->initlock, 1) == 1)
- Sleep(0);
- if (mutex->handle == NULL)
- mutex->handle = CreateMutex(NULL, FALSE, NULL);
- InterlockedExchange((LONG *) &mutex->initlock, 0);
- }
-}
-
-static pthread_mutex_t win32_pthread_once_lock = PTHREAD_MUTEX_INITIALIZER;
-
-void
-win32_pthread_once(volatile pthread_once_t *once, void (*fn) (void))
-{
- if (!*once)
- {
- pthread_mutex_lock(&win32_pthread_once_lock);
- if (!*once)
- {
- fn();
- *once = true;
- }
- pthread_mutex_unlock(&win32_pthread_once_lock);
- }
-}
-#endif /* WIN32 */
-
#ifdef ENABLE_NLS
char *
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index 081e32666f..7231cc4a6f 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -11,7 +11,6 @@
#include "catalog/pg_type_d.h"
#include "decimal.h"
-#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
diff --git a/src/interfaces/ecpg/include/ecpg-pthread-win32.h b/src/interfaces/ecpg/include/ecpg-pthread-win32.h
deleted file mode 100644
index 8252a17809..0000000000
--- a/src/interfaces/ecpg/include/ecpg-pthread-win32.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* src/interfaces/ecpg/include/ecpg-pthread-win32.h */
-/*
- * pthread mapping macros for win32 native thread implementation
- */
-#ifndef _ECPG_PTHREAD_WIN32_H
-#define _ECPG_PTHREAD_WIN32_H
-
-#ifndef WIN32
-
-#include <pthread.h>
-#else
-
-typedef struct pthread_mutex_t
-{
- HANDLE handle;
- LONG initlock;
-} pthread_mutex_t;
-
-typedef DWORD pthread_key_t;
-typedef bool pthread_once_t;
-
-#define PTHREAD_MUTEX_INITIALIZER { NULL, 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));
-
-#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))
-
-#define pthread_setspecific(key, value) \
- TlsSetValue((key), (value))
-
-/* FIXME: destructor is never called in Win32. */
-#define pthread_key_create(key, destructor) \
- do { *(key) = TlsAlloc(); ((void)(destructor)); } while(0)
-
-#define pthread_once(once, fn) \
- do { \
- if (!*(once)) \
- win32_pthread_once((once), (fn)); \
- } while(0)
-#endif /* WIN32 */
-
-#endif /* _ECPG_PTHREAD_WIN32_H */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index 6d01608a49..e693c9074f 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -10,5 +10,8 @@
/* Define to 1 if `long long int' works and is 64 bits. */
#undef HAVE_LONG_LONG_INT_64
+/* Define to 1 if you have the `pthread_barrier_wait' function. */
+#undef HAVE_PTHREAD_BARRIER_WAIT
+
/* Define to 1 to use <stdbool.h> to define type bool. */
#undef PG_USE_STDBOOL
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index 543e48fd6e..2e93efde98 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -6,6 +6,7 @@ ecpg_conf_keys = [
'HAVE_INT64',
'HAVE_LONG_INT_64',
'HAVE_LONG_LONG_INT_64',
+ 'HAVE_PTHREAD_BARRIER_WAIT',
'PG_USE_STDBOOL',
]
diff --git a/src/interfaces/ecpg/test/expected/thread-alloc.c b/src/interfaces/ecpg/test/expected/thread-alloc.c
index 3b31d27fd3..97ed928ef1 100644
--- a/src/interfaces/ecpg/test/expected/thread-alloc.c
+++ b/src/interfaces/ecpg/test/expected/thread-alloc.c
@@ -10,16 +10,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
-#include <stdio.h>
+#include "port/pg_threads.h"
#define THREADS 16
#define REPEATS 50
@@ -93,7 +84,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
-#line 18 "alloc.pgc"
+#line 9 "alloc.pgc"
#line 1 "regression.h"
@@ -103,21 +94,17 @@ struct sqlca_t *ECPGget_sqlca(void);
-#line 19 "alloc.pgc"
+#line 10 "alloc.pgc"
/* exec sql whenever sqlerror sqlprint ; */
-#line 21 "alloc.pgc"
+#line 12 "alloc.pgc"
/* exec sql whenever not found sqlprint ; */
-#line 22 "alloc.pgc"
+#line 13 "alloc.pgc"
-#ifdef WIN32
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
@@ -126,54 +113,54 @@ static void* fn(void* arg)
-#line 33 "alloc.pgc"
+#line 20 "alloc.pgc"
int value ;
-#line 34 "alloc.pgc"
+#line 21 "alloc.pgc"
char name [ 100 ] ;
-#line 35 "alloc.pgc"
+#line 22 "alloc.pgc"
char ** r = NULL ;
/* exec sql end declare section */
-#line 36 "alloc.pgc"
+#line 23 "alloc.pgc"
value = (intptr_t) arg;
sprintf(name, "Connection: %d", value);
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0);
-#line 41 "alloc.pgc"
+#line 28 "alloc.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 41 "alloc.pgc"
+#line 28 "alloc.pgc"
{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 42 "alloc.pgc"
+#line 29 "alloc.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 42 "alloc.pgc"
+#line 29 "alloc.pgc"
for (i = 1; i <= REPEATS; ++i)
{
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class'", ECPGt_EOIT,
ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 45 "alloc.pgc"
+#line 32 "alloc.pgc"
if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 45 "alloc.pgc"
+#line 32 "alloc.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 45 "alloc.pgc"
+#line 32 "alloc.pgc"
free(r);
r = NULL;
}
{ ECPGdisconnect(__LINE__, name);
-#line 49 "alloc.pgc"
+#line 36 "alloc.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "alloc.pgc"
+#line 36 "alloc.pgc"
return 0;
@@ -182,28 +169,12 @@ if (sqlca.sqlcode < 0) sqlprint();}
int main ()
{
intptr_t i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
-
-#ifdef WIN32
- for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id);
- }
+ pg_thrd_t threads[THREADS];
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
+ pg_thrd_create(&threads[i], fn, (void *) i);
for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, (void *) i);
- for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/expected/thread-descriptor.c b/src/interfaces/ecpg/test/expected/thread-descriptor.c
index e34f4708d1..50cdbf1b2f 100644
--- a/src/interfaces/ecpg/test/expected/thread-descriptor.c
+++ b/src/interfaces/ecpg/test/expected/thread-descriptor.c
@@ -7,15 +7,7 @@
#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
#line 1 "descriptor.pgc"
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
-#include <stdio.h>
+#include "port/pg_threads.h"
#define THREADS 16
#define REPEATS 50000
@@ -89,36 +81,32 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
-#line 14 "descriptor.pgc"
+#line 6 "descriptor.pgc"
/* exec sql whenever sqlerror sqlprint ; */
-#line 15 "descriptor.pgc"
+#line 7 "descriptor.pgc"
/* exec sql whenever not found sqlprint ; */
-#line 16 "descriptor.pgc"
+#line 8 "descriptor.pgc"
-#if defined(WIN32)
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
for (i = 1; i <= REPEATS; ++i)
{
ECPGallocate_desc(__LINE__, "mydesc");
-#line 28 "descriptor.pgc"
+#line 16 "descriptor.pgc"
if (sqlca.sqlcode < 0) sqlprint();
-#line 28 "descriptor.pgc"
+#line 16 "descriptor.pgc"
ECPGdeallocate_desc(__LINE__, "mydesc");
-#line 29 "descriptor.pgc"
+#line 17 "descriptor.pgc"
if (sqlca.sqlcode < 0) sqlprint();
-#line 29 "descriptor.pgc"
+#line 17 "descriptor.pgc"
}
@@ -128,28 +116,12 @@ if (sqlca.sqlcode < 0) sqlprint();
int main ()
{
int i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
-
-#ifdef WIN32
- for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, NULL, 0, &id);
- }
+ pg_thrd_t threads[THREADS];
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
- for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, NULL);
+ pg_thrd_create(&threads[i], fn, NULL);
for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/expected/thread-prep.c b/src/interfaces/ecpg/test/expected/thread-prep.c
index 052e27b634..c5b60d18cb 100644
--- a/src/interfaces/ecpg/test/expected/thread-prep.c
+++ b/src/interfaces/ecpg/test/expected/thread-prep.c
@@ -10,15 +10,8 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
+#include "port/pg_threads.h"
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
#include <stdio.h>
#define THREADS 16
@@ -93,7 +86,7 @@ struct sqlca_t *ECPGget_sqlca(void);
#endif
-#line 18 "prep.pgc"
+#line 11 "prep.pgc"
#line 1 "regression.h"
@@ -103,21 +96,17 @@ struct sqlca_t *ECPGget_sqlca(void);
-#line 19 "prep.pgc"
+#line 12 "prep.pgc"
/* exec sql whenever sqlerror sqlprint ; */
-#line 21 "prep.pgc"
+#line 14 "prep.pgc"
/* exec sql whenever not found sqlprint ; */
-#line 22 "prep.pgc"
+#line 15 "prep.pgc"
-#ifdef WIN32
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
@@ -126,64 +115,64 @@ static void* fn(void* arg)
-#line 33 "prep.pgc"
+#line 22 "prep.pgc"
int value ;
-#line 34 "prep.pgc"
+#line 23 "prep.pgc"
char name [ 100 ] ;
-#line 35 "prep.pgc"
+#line 24 "prep.pgc"
char query [ 256 ] = "INSERT INTO T VALUES ( ? )" ;
/* exec sql end declare section */
-#line 36 "prep.pgc"
+#line 25 "prep.pgc"
value = (intptr_t) arg;
sprintf(name, "Connection: %d", value);
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , name, 0);
-#line 41 "prep.pgc"
+#line 30 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 41 "prep.pgc"
+#line 30 "prep.pgc"
{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 42 "prep.pgc"
+#line 31 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 42 "prep.pgc"
+#line 31 "prep.pgc"
for (i = 1; i <= REPEATS; ++i)
{
{ ECPGprepare(__LINE__, NULL, 0, "i", query);
-#line 45 "prep.pgc"
+#line 34 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 45 "prep.pgc"
+#line 34 "prep.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "i",
ECPGt_int,&(value),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 46 "prep.pgc"
+#line 35 "prep.pgc"
if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
-#line 46 "prep.pgc"
+#line 35 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 46 "prep.pgc"
+#line 35 "prep.pgc"
}
{ ECPGdeallocate(__LINE__, 0, NULL, "i");
-#line 48 "prep.pgc"
+#line 37 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 48 "prep.pgc"
+#line 37 "prep.pgc"
{ ECPGdisconnect(__LINE__, name);
-#line 49 "prep.pgc"
+#line 38 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 49 "prep.pgc"
+#line 38 "prep.pgc"
return 0;
@@ -192,59 +181,43 @@ if (sqlca.sqlcode < 0) sqlprint();}
int main ()
{
intptr_t i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
+ pg_thrd_t threads[THREADS];
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0);
-#line 63 "prep.pgc"
+#line 48 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 63 "prep.pgc"
+#line 48 "prep.pgc"
{ ECPGsetcommit(__LINE__, "on", NULL);
-#line 64 "prep.pgc"
+#line 49 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 64 "prep.pgc"
+#line 49 "prep.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table if exists T", ECPGt_EOIT, ECPGt_EORT);
-#line 65 "prep.pgc"
+#line 50 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 65 "prep.pgc"
+#line 50 "prep.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table T ( i int )", ECPGt_EOIT, ECPGt_EORT);
-#line 66 "prep.pgc"
+#line 51 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 66 "prep.pgc"
+#line 51 "prep.pgc"
{ ECPGdisconnect(__LINE__, "CURRENT");
-#line 67 "prep.pgc"
+#line 52 "prep.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 67 "prep.pgc"
+#line 52 "prep.pgc"
-#ifdef WIN32
for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id);
- }
-
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
+ pg_thrd_create(&threads[i], fn, (void *) i);
for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
- for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, (void *) i);
- for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 95faa223c2..03c7169995 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -14,13 +14,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include <windows.h>
-#include <locale.h>
-#endif
+#include "port/pg_threads.h"
#line 1 "regression.h"
@@ -30,29 +24,25 @@
-#line 16 "thread.pgc"
+#line 10 "thread.pgc"
-void *test_thread(void *arg);
+int test_thread(void *arg);
int nthreads = 10;
int iterations = 20;
int main()
{
-#ifndef WIN32
- pthread_t *threads;
-#else
- HANDLE *threads;
-#endif
+ pg_thrd_t *threads;
intptr_t n;
/* exec sql begin declare section */
-#line 32 "thread.pgc"
+#line 22 "thread.pgc"
int l_rows ;
/* exec sql end declare section */
-#line 33 "thread.pgc"
+#line 23 "thread.pgc"
/* Do not switch on debug output for regression tests. The threads get executed in
@@ -61,22 +51,22 @@ int main()
/* setup test_thread table */
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 40 "thread.pgc"
+#line 30 "thread.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 41 "thread.pgc"
+#line 31 "thread.pgc"
/* DROP might fail */
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 42 "thread.pgc"
+#line 32 "thread.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 47 "thread.pgc"
+#line 37 "thread.pgc"
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 48 "thread.pgc"
+#line 38 "thread.pgc"
{ ECPGdisconnect(__LINE__, "CURRENT");}
-#line 49 "thread.pgc"
+#line 39 "thread.pgc"
/* create, and start, threads */
@@ -87,39 +77,27 @@ int main()
return 1;
}
for( n = 0; n < nthreads; n++ )
- {
-#ifndef WIN32
- pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
-#else
- threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n + 1), 0, NULL);
-#endif
- }
+ pg_thrd_create(&threads[n], test_thread, (void *) (n + 1));
/* wait for thread completion */
-#ifndef WIN32
for( n = 0; n < nthreads; n++ )
- {
- pthread_join(threads[n], NULL);
- }
-#else
- WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
-#endif
+ pg_thrd_join(threads[n], NULL);
free(threads);
/* and check results */
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 79 "thread.pgc"
+#line 57 "thread.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT,
ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 80 "thread.pgc"
+#line 58 "thread.pgc"
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 81 "thread.pgc"
+#line 59 "thread.pgc"
{ ECPGdisconnect(__LINE__, "CURRENT");}
-#line 82 "thread.pgc"
+#line 60 "thread.pgc"
if( l_rows == (nthreads * iterations) )
printf("Success.\n");
@@ -129,7 +107,7 @@ int main()
return 0;
}
-void *test_thread(void *arg)
+int test_thread(void *arg)
{
long threadnum = (intptr_t) arg;
@@ -137,13 +115,13 @@ void *test_thread(void *arg)
-#line 96 "thread.pgc"
+#line 74 "thread.pgc"
int l_i ;
-#line 97 "thread.pgc"
+#line 75 "thread.pgc"
char l_connection [ 128 ] ;
/* exec sql end declare section */
-#line 98 "thread.pgc"
+#line 76 "thread.pgc"
/* build up connection name, and connect to database */
@@ -153,24 +131,24 @@ void *test_thread(void *arg)
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
#endif
/* exec sql whenever sqlerror sqlprint ; */
-#line 106 "thread.pgc"
+#line 84 "thread.pgc"
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0);
-#line 107 "thread.pgc"
+#line 85 "thread.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 107 "thread.pgc"
+#line 85 "thread.pgc"
if( sqlca.sqlcode != 0 )
{
printf("%s: ERROR: cannot connect to database!\n", l_connection);
- return NULL;
+ return 0;
}
{ ECPGtrans(__LINE__, l_connection, "begin");
-#line 113 "thread.pgc"
+#line 91 "thread.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 113 "thread.pgc"
+#line 91 "thread.pgc"
/* insert into test_thread table */
@@ -181,10 +159,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 118 "thread.pgc"
+#line 96 "thread.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 118 "thread.pgc"
+#line 96 "thread.pgc"
if( sqlca.sqlcode != 0 )
printf("%s: ERROR: insert failed!\n", l_connection);
@@ -192,16 +170,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
/* all done */
{ ECPGtrans(__LINE__, l_connection, "commit");
-#line 124 "thread.pgc"
+#line 102 "thread.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 124 "thread.pgc"
+#line 102 "thread.pgc"
{ ECPGdisconnect(__LINE__, l_connection);
-#line 125 "thread.pgc"
+#line 103 "thread.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 125 "thread.pgc"
+#line 103 "thread.pgc"
- return NULL;
+ return 0;
}
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 7ac0297a23..c859012f50 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -14,13 +14,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include <windows.h>
-#include <locale.h>
-#endif
+#include "port/pg_threads.h"
#line 1 "regression.h"
@@ -30,29 +24,25 @@
-#line 16 "thread_implicit.pgc"
+#line 10 "thread_implicit.pgc"
-void *test_thread(void *arg);
+int test_thread(void *arg);
int nthreads = 10;
int iterations = 20;
int main()
{
-#ifndef WIN32
- pthread_t *threads;
-#else
- HANDLE *threads;
-#endif
+ pg_thrd_t *threads;
intptr_t n;
/* exec sql begin declare section */
-#line 32 "thread_implicit.pgc"
+#line 22 "thread_implicit.pgc"
int l_rows ;
/* exec sql end declare section */
-#line 33 "thread_implicit.pgc"
+#line 23 "thread_implicit.pgc"
/* Do not switch on debug output for regression tests. The threads get executed in
@@ -61,22 +51,22 @@ int main()
/* setup test_thread table */
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 40 "thread_implicit.pgc"
+#line 30 "thread_implicit.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test_thread", ECPGt_EOIT, ECPGt_EORT);}
-#line 41 "thread_implicit.pgc"
+#line 31 "thread_implicit.pgc"
/* DROP might fail */
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 42 "thread_implicit.pgc"
+#line 32 "thread_implicit.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test_thread ( tstamp timestamp not null default cast ( timeofday ( ) as timestamp ) , thread text not null , iteration integer not null , primary key ( thread , iteration ) )", ECPGt_EOIT, ECPGt_EORT);}
-#line 47 "thread_implicit.pgc"
+#line 37 "thread_implicit.pgc"
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 48 "thread_implicit.pgc"
+#line 38 "thread_implicit.pgc"
{ ECPGdisconnect(__LINE__, "CURRENT");}
-#line 49 "thread_implicit.pgc"
+#line 39 "thread_implicit.pgc"
/* create, and start, threads */
@@ -87,39 +77,27 @@ int main()
return 1;
}
for( n = 0; n < nthreads; n++ )
- {
-#ifndef WIN32
- pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
-#else
- threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n+1), 0, NULL);
-#endif
- }
+ pg_thrd_create(&threads[n], test_thread, (void *) (n + 1));
/* wait for thread completion */
-#ifndef WIN32
for( n = 0; n < nthreads; n++ )
- {
- pthread_join(threads[n], NULL);
- }
-#else
- WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
-#endif
+ pg_thrd_join(threads[n], NULL);
free(threads);
/* and check results */
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); }
-#line 79 "thread_implicit.pgc"
+#line 57 "thread_implicit.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select count ( * ) from test_thread", ECPGt_EOIT,
ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 80 "thread_implicit.pgc"
+#line 58 "thread_implicit.pgc"
{ ECPGtrans(__LINE__, NULL, "commit");}
-#line 81 "thread_implicit.pgc"
+#line 59 "thread_implicit.pgc"
{ ECPGdisconnect(__LINE__, "CURRENT");}
-#line 82 "thread_implicit.pgc"
+#line 60 "thread_implicit.pgc"
if( l_rows == (nthreads * iterations) )
printf("Success.\n");
@@ -129,7 +107,7 @@ int main()
return 0;
}
-void *test_thread(void *arg)
+int test_thread(void *arg)
{
long threadnum = (intptr_t) arg;
@@ -137,13 +115,13 @@ void *test_thread(void *arg)
-#line 96 "thread_implicit.pgc"
+#line 74 "thread_implicit.pgc"
int l_i ;
-#line 97 "thread_implicit.pgc"
+#line 75 "thread_implicit.pgc"
char l_connection [ 128 ] ;
/* exec sql end declare section */
-#line 98 "thread_implicit.pgc"
+#line 76 "thread_implicit.pgc"
/* build up connection name, and connect to database */
@@ -153,24 +131,24 @@ void *test_thread(void *arg)
_snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
#endif
/* exec sql whenever sqlerror sqlprint ; */
-#line 106 "thread_implicit.pgc"
+#line 84 "thread_implicit.pgc"
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , l_connection, 0);
-#line 107 "thread_implicit.pgc"
+#line 85 "thread_implicit.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 107 "thread_implicit.pgc"
+#line 85 "thread_implicit.pgc"
if( sqlca.sqlcode != 0 )
{
printf("%s: ERROR: cannot connect to database!\n", l_connection);
- return NULL;
+ return 0;
}
{ ECPGtrans(__LINE__, NULL, "begin");
-#line 113 "thread_implicit.pgc"
+#line 91 "thread_implicit.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 113 "thread_implicit.pgc"
+#line 91 "thread_implicit.pgc"
/* insert into test_thread table */
@@ -181,10 +159,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 118 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 118 "thread_implicit.pgc"
+#line 96 "thread_implicit.pgc"
if( sqlca.sqlcode != 0 )
printf("%s: ERROR: insert failed!\n", l_connection);
@@ -192,16 +170,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
/* all done */
{ ECPGtrans(__LINE__, NULL, "commit");
-#line 124 "thread_implicit.pgc"
+#line 102 "thread_implicit.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 124 "thread_implicit.pgc"
+#line 102 "thread_implicit.pgc"
{ ECPGdisconnect(__LINE__, l_connection);
-#line 125 "thread_implicit.pgc"
+#line 103 "thread_implicit.pgc"
if (sqlca.sqlcode < 0) sqlprint();}
-#line 125 "thread_implicit.pgc"
+#line 103 "thread_implicit.pgc"
- return NULL;
+ return 0;
}
diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc
index d3d35493bf..248a29447c 100644
--- a/src/interfaces/ecpg/test/thread/alloc.pgc
+++ b/src/interfaces/ecpg/test/thread/alloc.pgc
@@ -1,16 +1,7 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
-#include <stdio.h>
+#include "port/pg_threads.h"
#define THREADS 16
#define REPEATS 50
@@ -21,11 +12,7 @@ exec sql include ../regression;
exec sql whenever sqlerror sqlprint;
exec sql whenever not found sqlprint;
-#ifdef WIN32
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
@@ -54,28 +41,12 @@ static void* fn(void* arg)
int main ()
{
intptr_t i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
-
-#ifdef WIN32
- for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id);
- }
+ pg_thrd_t threads[THREADS];
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
- for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, (void *) i);
+ pg_thrd_create(&threads[i], fn, (void *) i);
for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc
index 30bce7c87b..faa9a0a656 100644
--- a/src/interfaces/ecpg/test/thread/descriptor.pgc
+++ b/src/interfaces/ecpg/test/thread/descriptor.pgc
@@ -1,12 +1,4 @@
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
-#include <stdio.h>
+#include "port/pg_threads.h"
#define THREADS 16
#define REPEATS 50000
@@ -15,11 +7,7 @@ EXEC SQL include sqlca;
EXEC SQL whenever sqlerror sqlprint;
EXEC SQL whenever not found sqlprint;
-#if defined(WIN32)
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
@@ -35,28 +23,12 @@ static void* fn(void* arg)
int main ()
{
int i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
+ pg_thrd_t threads[THREADS];
-#ifdef WIN32
for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, NULL, 0, &id);
- }
-
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
- for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
- for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, NULL);
+ pg_thrd_create(&threads[i], fn, NULL);
for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc
index f61b31ce10..f5a875cc28 100644
--- a/src/interfaces/ecpg/test/thread/prep.pgc
+++ b/src/interfaces/ecpg/test/thread/prep.pgc
@@ -1,15 +1,8 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
+#include "port/pg_threads.h"
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <locale.h>
-#else
-#include <pthread.h>
-#endif
#include <stdio.h>
#define THREADS 16
@@ -21,11 +14,7 @@ exec sql include ../regression;
exec sql whenever sqlerror sqlprint;
exec sql whenever not found sqlprint;
-#ifdef WIN32
-static unsigned __stdcall fn(void* arg)
-#else
-static void* fn(void* arg)
-#endif
+static int fn(void* arg)
{
int i;
@@ -54,11 +43,7 @@ static void* fn(void* arg)
int main ()
{
intptr_t i;
-#ifdef WIN32
- HANDLE threads[THREADS];
-#else
- pthread_t threads[THREADS];
-#endif
+ pg_thrd_t threads[THREADS];
EXEC SQL CONNECT TO REGRESSDB1;
EXEC SQL SET AUTOCOMMIT TO ON;
@@ -66,22 +51,10 @@ int main ()
EXEC SQL CREATE TABLE T ( i int );
EXEC SQL DISCONNECT;
-#ifdef WIN32
for (i = 0; i < THREADS; ++i)
- {
- unsigned id;
- threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id);
- }
-
- WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE);
- for (i = 0; i < THREADS; ++i)
- CloseHandle(threads[i]);
-#else
- for (i = 0; i < THREADS; ++i)
- pthread_create(&threads[i], NULL, fn, (void *) i);
+ pg_thrd_create(&threads[i], fn, (void *) i);
for (i = 0; i < THREADS; ++i)
- pthread_join(threads[i], NULL);
-#endif
+ pg_thrd_join(threads[i], NULL);
return 0;
}
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index b9b9ebb441..bc967b9da8 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -5,28 +5,18 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include <windows.h>
-#include <locale.h>
-#endif
+#include "port/pg_threads.h"
exec sql include ../regression;
-void *test_thread(void *arg);
+int test_thread(void *arg);
int nthreads = 10;
int iterations = 20;
int main()
{
-#ifndef WIN32
- pthread_t *threads;
-#else
- HANDLE *threads;
-#endif
+ pg_thrd_t *threads;
intptr_t n;
EXEC SQL BEGIN DECLARE SECTION;
int l_rows;
@@ -56,23 +46,11 @@ int main()
return 1;
}
for( n = 0; n < nthreads; n++ )
- {
-#ifndef WIN32
- pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
-#else
- threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n + 1), 0, NULL);
-#endif
- }
+ pg_thrd_create(&threads[n], test_thread, (void *) (n + 1));
/* wait for thread completion */
-#ifndef WIN32
for( n = 0; n < nthreads; n++ )
- {
- pthread_join(threads[n], NULL);
- }
-#else
- WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
-#endif
+ pg_thrd_join(threads[n], NULL);
free(threads);
/* and check results */
@@ -88,7 +66,7 @@ int main()
return 0;
}
-void *test_thread(void *arg)
+int test_thread(void *arg)
{
long threadnum = (intptr_t) arg;
@@ -108,7 +86,7 @@ void *test_thread(void *arg)
if( sqlca.sqlcode != 0 )
{
printf("%s: ERROR: cannot connect to database!\n", l_connection);
- return NULL;
+ return 0;
}
EXEC SQL AT :l_connection BEGIN;
@@ -123,5 +101,5 @@ void *test_thread(void *arg)
/* all done */
EXEC SQL AT :l_connection COMMIT;
EXEC SQL DISCONNECT :l_connection;
- return NULL;
+ return 0;
}
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index ff9b12a943..7a793dc7f8 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -5,28 +5,18 @@
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"
-
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include <windows.h>
-#include <locale.h>
-#endif
+#include "port/pg_threads.h"
exec sql include ../regression;
-void *test_thread(void *arg);
+int test_thread(void *arg);
int nthreads = 10;
int iterations = 20;
int main()
{
-#ifndef WIN32
- pthread_t *threads;
-#else
- HANDLE *threads;
-#endif
+ pg_thrd_t *threads;
intptr_t n;
EXEC SQL BEGIN DECLARE SECTION;
int l_rows;
@@ -56,23 +46,11 @@ int main()
return 1;
}
for( n = 0; n < nthreads; n++ )
- {
-#ifndef WIN32
- pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
-#else
- threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n+1), 0, NULL);
-#endif
- }
+ pg_thrd_create(&threads[n], test_thread, (void *) (n + 1));
/* wait for thread completion */
-#ifndef WIN32
for( n = 0; n < nthreads; n++ )
- {
- pthread_join(threads[n], NULL);
- }
-#else
- WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
-#endif
+ pg_thrd_join(threads[n], NULL);
free(threads);
/* and check results */
@@ -88,7 +66,7 @@ int main()
return 0;
}
-void *test_thread(void *arg)
+int test_thread(void *arg)
{
long threadnum = (intptr_t) arg;
@@ -108,7 +86,7 @@ void *test_thread(void *arg)
if( sqlca.sqlcode != 0 )
{
printf("%s: ERROR: cannot connect to database!\n", l_connection);
- return NULL;
+ return 0;
}
EXEC SQL BEGIN;
@@ -123,5 +101,5 @@ void *test_thread(void *arg)
/* all done */
EXEC SQL COMMIT;
EXEC SQL DISCONNECT :l_connection;
- return NULL;
+ return 0;
}
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 46653682b0..62269ddbf4 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -69,7 +69,6 @@ endif
ifeq ($(PORTNAME), win32)
OBJS += \
- pthread-win32.o \
win32.o
endif
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 837c5321aa..7806f67879 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -32,6 +32,7 @@
#include "mb/pg_wchar.h"
#include "pg_config_paths.h"
#include "port/pg_bswap.h"
+#include "port/pg_threads.h"
#ifdef WIN32
#include "win32.h"
@@ -52,12 +53,6 @@
#include <netinet/tcp.h>
#endif
-#ifdef WIN32
-#include "pthread-win32.h"
-#else
-#include <pthread.h>
-#endif
-
#ifdef USE_LDAP
#ifdef WIN32
#include <winldap.h>
@@ -7779,35 +7774,29 @@ pqGetHomeDirectory(char *buf, int bufsize)
* the field.
*/
+static pg_mtx_t singlethread_lock;
+
+static void
+singlethread_lock_init(void)
+{
+ pg_mtx_init(&singlethread_lock, pg_mtx_plain);
+}
+
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;
+ static pg_once_flag singlethread_lock_once = PG_ONCE_FLAG_INIT;
+
+ pg_call_once(&singlethread_lock_once, singlethread_lock_init);
- 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))
+ if (pg_mtx_lock(&singlethread_lock) != pg_thrd_success)
Assert(false);
}
else
{
- if (pthread_mutex_unlock(&singlethread_lock))
+ if (pg_mtx_unlock(&singlethread_lock) != pg_thrd_success)
Assert(false);
}
}
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 4976d963a2..dcbab932ee 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -30,6 +30,7 @@
#include "fe-auth.h"
#include "fe-secure-common.h"
#include "libpq-int.h"
+#include "port/pg_threads.h"
#ifdef WIN32
#include "win32.h"
@@ -44,12 +45,6 @@
#include <sys/stat.h>
-#ifdef WIN32
-#include "pthread-win32.h"
-#else
-#include <pthread.h>
-#endif
-
/*
* These SSL-related #includes must come after all system-provided headers.
* This ensures that OpenSSL can take care of conflicts with Windows'
@@ -91,12 +86,8 @@ 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 pg_mtx_t ssl_config_mutex;
+static pg_once_flag ssl_config_mutex_once = PG_ONCE_FLAG_INIT;
static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
static int ssl_protocol_version_to_openssl(const char *protocol);
@@ -726,14 +717,14 @@ static unsigned long
pq_threadidcallback(void)
{
/*
- * This is not standards-compliant. pthread_self() returns pthread_t, and
+ * This is not standards-compliant. thrd_currnt() returns thrd_t, and
* shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
* it, so we have to do it.
*/
- return (unsigned long) pthread_self();
+ return (unsigned long) thrd_current();
}
-static pthread_mutex_t *pq_lockarray;
+static pg_mtx_t *pq_lockarray;
static void
pq_lockingcallback(int mode, int n, const char *file, int line)
@@ -745,17 +736,23 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
*/
if (mode & CRYPTO_LOCK)
{
- if (pthread_mutex_lock(&pq_lockarray[n]))
+ if (pg_mtx_lock(&pq_lockarray[n]) != pg_thrd_success)
Assert(false);
}
else
{
- if (pthread_mutex_unlock(&pq_lockarray[n]))
+ if (pg_mtx_unlock(&pq_lockarray[n]) != pg_thrd_success)
Assert(false);
}
}
#endif /* HAVE_CRYPTO_LOCK */
+static void
+ssl_config_mutex_init(void)
+{
+ pg_mtx_init(&ssl_config_mutex, pg_mtx_plain);
+}
+
/*
* Initialize SSL library.
*
@@ -769,21 +766,9 @@ 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))
+ pg_call_once(&ssl_config_mutex_once, ssl_config_mutex_init);
+
+ if (pg_mtx_lock(&ssl_config_mutex) != pg_thrd_success)
return -1;
#ifdef HAVE_CRYPTO_LOCK
@@ -797,19 +782,19 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
{
int i;
- pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
+ pq_lockarray = malloc(sizeof(pg_mtx_t) * CRYPTO_num_locks());
if (!pq_lockarray)
{
- pthread_mutex_unlock(&ssl_config_mutex);
+ pg_mtx_unlock(&ssl_config_mutex);
return -1;
}
for (i = 0; i < CRYPTO_num_locks(); i++)
{
- if (pthread_mutex_init(&pq_lockarray[i], NULL))
+ if (pg_mtx_init(&pq_lockarray[i], NULL) != pg_thrd_success)
{
free(pq_lockarray);
pq_lockarray = NULL;
- pthread_mutex_unlock(&ssl_config_mutex);
+ pg_mtx_unlock(&ssl_config_mutex);
return -1;
}
}
@@ -850,7 +835,7 @@ pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
ssl_lib_initialized = true;
}
- pthread_mutex_unlock(&ssl_config_mutex);
+ pg_mtx_unlock(&ssl_config_mutex);
return 0;
}
@@ -871,7 +856,7 @@ destroy_ssl_system(void)
{
#if defined(HAVE_CRYPTO_LOCK)
/* Mutex is created in pgtls_init() */
- if (pthread_mutex_lock(&ssl_config_mutex))
+ if (pg_mtx_lock(&ssl_config_mutex) != pg_thrd_success)
return;
if (pq_init_crypto_lib && crypto_open_connections > 0)
@@ -897,7 +882,7 @@ destroy_ssl_system(void)
*/
}
- pthread_mutex_unlock(&ssl_config_mutex);
+ pg_mtx_unlock(&ssl_config_mutex);
#endif
}
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index bd72a87bbb..804b5e30aa 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -35,9 +35,7 @@
#include <sys/stat.h>
-#ifdef WIN32
-#include "pthread-win32.h"
-#else
+#ifndef WIN32
#include <pthread.h>
#endif
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 10f20c1175..870db73841 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -31,11 +31,6 @@
#include <sys/time.h>
#endif
-#ifdef WIN32
-#include "pthread-win32.h"
-#else
-#include <pthread.h>
-#endif
#include <signal.h>
/* include stuff common to fe and be */
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 80e6a15adf..6aa0276209 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -21,7 +21,7 @@ libpq_sources = files(
libpq_so_sources = [] # for shared lib, in addition to the above
if host_system == 'windows'
- libpq_sources += files('pthread-win32.c', 'win32.c')
+ libpq_sources += files('win32.c')
libpq_so_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
'--NAME', 'libpq',
'--FILEDESC', 'PostgreSQL Access Library',])
@@ -43,7 +43,7 @@ export_file = custom_target('libpq.exports',
kwargs: gen_export_kwargs,
)
-# port needs to be in include path due to pthread-win32.h
+# XXX why do we need this?
libpq_inc = include_directories('.', '../../port')
libpq_c_args = ['-DSO_MAJOR_VERSION=5']
diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c
deleted file mode 100644
index 8e65637387..0000000000
--- a/src/interfaces/libpq/pthread-win32.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-------------------------------------------------------------------------
-*
-* pthread-win32.c
-* partial pthread implementation for win32
-*
-* Copyright (c) 2004-2023, PostgreSQL Global Development Group
-* IDENTIFICATION
-* src/interfaces/libpq/pthread-win32.c
-*
-*-------------------------------------------------------------------------
-*/
-
-#include "postgres_fe.h"
-
-#include "pthread-win32.h"
-
-DWORD
-pthread_self(void)
-{
- return GetCurrentThreadId();
-}
-
-void
-pthread_setspecific(pthread_key_t key, void *val)
-{
-}
-
-void *
-pthread_getspecific(pthread_key_t key)
-{
- return NULL;
-}
-
-int
-pthread_mutex_init(pthread_mutex_t *mp, void *attr)
-{
- *mp = (CRITICAL_SECTION *) malloc(sizeof(CRITICAL_SECTION));
- if (!*mp)
- return 1;
- InitializeCriticalSection(*mp);
- return 0;
-}
-
-int
-pthread_mutex_lock(pthread_mutex_t *mp)
-{
- if (!*mp)
- return 1;
- EnterCriticalSection(*mp);
- return 0;
-}
-
-int
-pthread_mutex_unlock(pthread_mutex_t *mp)
-{
- if (!*mp)
- return 1;
- LeaveCriticalSection(*mp);
- return 0;
-}
diff --git a/src/port/pthread-win32.h b/src/port/pthread-win32.h
deleted file mode 100644
index 97ccc17a12..0000000000
--- a/src/port/pthread-win32.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * src/port/pthread-win32.h
- */
-#ifndef __PTHREAD_H
-#define __PTHREAD_H
-
-typedef ULONG pthread_key_t;
-typedef CRITICAL_SECTION *pthread_mutex_t;
-typedef int pthread_once_t;
-
-DWORD pthread_self(void);
-
-void pthread_setspecific(pthread_key_t, void *);
-void *pthread_getspecific(pthread_key_t);
-
-int pthread_mutex_init(pthread_mutex_t *, void *attr);
-int pthread_mutex_lock(pthread_mutex_t *);
-
-/* blocking */
-int pthread_mutex_unlock(pthread_mutex_t *);
-
-#endif
diff --git a/src/tools/pginclude/cpluspluscheck b/src/tools/pginclude/cpluspluscheck
index 4e09c4686b..121c7a2684 100755
--- a/src/tools/pginclude/cpluspluscheck
+++ b/src/tools/pginclude/cpluspluscheck
@@ -79,7 +79,6 @@ do
test "$f" = src/include/port/win32_msvc/dirent.h && continue
test "$f" = src/include/port/win32_msvc/utime.h && continue
test "$f" = src/include/port/win32ntdll.h && continue
- test "$f" = src/port/pthread-win32.h && continue
# Likewise, these files are platform-specific, and the one
# relevant to our platform will be included by atomics.h.
diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 8dee1b5670..b42467dfc6 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -74,7 +74,6 @@ do
test "$f" = src/include/port/win32_msvc/dirent.h && continue
test "$f" = src/include/port/win32_msvc/utime.h && continue
test "$f" = src/include/port/win32ntdll.h && continue
- test "$f" = src/port/pthread-win32.h && continue
# Likewise, these files are platform-specific, and the one
# relevant to our platform will be included by atomics.h.
--
2.39.2