From ee27584c4a40620fb26d1729e9cc449d54d62b07 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 21 Jan 2019 16:17:10 -0500 Subject: [PATCH] Second try at fixing ecpglib thread-safety problem. While Windows (allegedly) has _configthreadlocale() pretty far back, it seems MinGW didn't acquire support for that till more recently. Fortunately, we can use an autoconf probe on that toolchain, instead of guessing whether it's there. (Hm, I wonder whether Cygwin will need this also.) Per buildfarm. Discussion: https://postgr.es/m/20190121193512.tdmcnic2yjxlufaw@alap3.anarazel.de --- configure | 11 +++++++++++ configure.in | 1 + src/include/pg_config.h.in | 3 +++ src/include/pg_config.h.win32 | 3 +++ src/interfaces/ecpg/ecpglib/descriptor.c | 4 ++-- src/interfaces/ecpg/ecpglib/ecpglib_extern.h | 2 +- src/interfaces/ecpg/ecpglib/execute.c | 6 +++--- 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 1e69edacde..ddb3c8b1ba 100755 --- a/configure +++ b/configure @@ -15942,6 +15942,17 @@ fi # Win32 (really MinGW) support if test "$PORTNAME" = "win32"; then + for ac_func in _configthreadlocale +do : + ac_fn_c_check_func "$LINENO" "_configthreadlocale" "ac_cv_func__configthreadlocale" +if test "x$ac_cv_func__configthreadlocale" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__CONFIGTHREADLOCALE 1 +_ACEOF + +fi +done + ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = xyes; then : $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h diff --git a/configure.in b/configure.in index 556186cf2d..3d8888805c 100644 --- a/configure.in +++ b/configure.in @@ -1754,6 +1754,7 @@ fi # Win32 (really MinGW) support if test "$PORTNAME" = "win32"; then + AC_CHECK_FUNCS(_configthreadlocale) AC_REPLACE_FUNCS(gettimeofday) AC_LIBOBJ(dirmod) AC_LIBOBJ(kill) diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 2c899a1569..82547f321f 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -757,6 +757,9 @@ /* Define to 1 if your compiler understands __builtin_unreachable. */ #undef HAVE__BUILTIN_UNREACHABLE +/* Define to 1 if you have the `_configthreadlocale' function. */ +#undef HAVE__CONFIGTHREADLOCALE + /* Define to 1 if you have __cpuid. */ #undef HAVE__CPUID diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 396443386a..a3c44f0fd8 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -596,6 +596,9 @@ /* Define to 1 if your compiler understands __builtin_unreachable. */ /* #undef HAVE__BUILTIN_UNREACHABLE */ +/* Define to 1 if you have the `_configthreadlocale' function. */ +#define HAVE__CONFIGTHREADLOCALE 1 + /* Define to 1 if you have __cpuid. */ #define HAVE__CPUID 1 diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index 71cef15172..aeb3363660 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -495,7 +495,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) if (stmt.clocale != (locale_t) 0) stmt.oldlocale = uselocale(stmt.clocale); #else -#ifdef WIN32 +#ifdef HAVE__CONFIGTHREADLOCALE stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); #endif stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); @@ -517,7 +517,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) setlocale(LC_NUMERIC, stmt.oldlocale); ecpg_free(stmt.oldlocale); } -#ifdef WIN32 +#ifdef HAVE__CONFIGTHREADLOCALE if (stmt.oldthreadlocale != -1) _configthreadlocale(stmt.oldthreadlocale); #endif diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index 41851d5900..ae2dcfc617 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -69,7 +69,7 @@ struct statement locale_t oldlocale; #else char *oldlocale; -#ifdef WIN32 +#ifdef HAVE__CONFIGTHREADLOCALE int oldthreadlocale; #endif #endif diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 81aaf10f08..a9f945e618 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1778,7 +1778,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, * Make sure we do NOT honor the locale for numeric input/output since the * database wants the standard decimal point. If available, use * uselocale() for this because it's thread-safe. Windows doesn't have - * that, but it does have _configthreadlocale(). + * that, but it usually does have _configthreadlocale(). */ #ifdef HAVE_USELOCALE stmt->clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0); @@ -1794,7 +1794,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, return false; } #else -#ifdef WIN32 +#ifdef HAVE__CONFIGTHREADLOCALE stmt->oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); if (stmt->oldthreadlocale == -1) { @@ -2019,7 +2019,7 @@ ecpg_do_epilogue(struct statement *stmt) if (stmt->oldlocale) { setlocale(LC_NUMERIC, stmt->oldlocale); -#ifdef WIN32 +#ifdef HAVE__CONFIGTHREADLOCALE _configthreadlocale(stmt->oldthreadlocale); #endif } -- 2.40.0