diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 19:16:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 19:16:24 +0000 |
commit | 2a0f262beff32ba86bcb58f3273214e5d0517c09 (patch) | |
tree | 24c0ad10dab36bbd5c22743d3c88c4e0ccd5bc65 /src/interfaces/libpq/fe-misc.c | |
parent | Releasing progress-linux version 16.2-2~progress7.99u1. (diff) | |
download | postgresql-16-2a0f262beff32ba86bcb58f3273214e5d0517c09.tar.xz postgresql-16-2a0f262beff32ba86bcb58f3273214e5d0517c09.zip |
Merging upstream version 16.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/interfaces/libpq/fe-misc.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 660cdec..488f7d6 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -1225,13 +1225,14 @@ static void libpq_binddomain(void) { /* - * If multiple threads come through here at about the same time, it's okay - * for more than one of them to call bindtextdomain(). But it's not okay - * for any of them to return to caller before bindtextdomain() is - * complete, so don't set the flag till that's done. Use "volatile" just - * to be sure the compiler doesn't try to get cute. + * At least on Windows, there are gettext implementations that fail if + * multiple threads call bindtextdomain() concurrently. Use a mutex and + * flag variable to ensure that we call it just once per process. It is + * not known that similar bugs exist on non-Windows platforms, but we + * might as well do it the same way everywhere. */ static volatile bool already_bound = false; + static pthread_mutex_t binddomain_mutex = PTHREAD_MUTEX_INITIALIZER; if (!already_bound) { @@ -1241,14 +1242,26 @@ libpq_binddomain(void) #else int save_errno = errno; #endif - const char *ldir; - - /* No relocatable lookup here because the binary could be anywhere */ - ldir = getenv("PGLOCALEDIR"); - if (!ldir) - ldir = LOCALEDIR; - bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir); - already_bound = true; + + (void) pthread_mutex_lock(&binddomain_mutex); + + if (!already_bound) + { + const char *ldir; + + /* + * No relocatable lookup here because the calling executable could + * be anywhere + */ + ldir = getenv("PGLOCALEDIR"); + if (!ldir) + ldir = LOCALEDIR; + bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir); + already_bound = true; + } + + (void) pthread_mutex_unlock(&binddomain_mutex); + #ifdef WIN32 SetLastError(save_errno); #else |