Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8dc8310

Browse files
committed
On Darwin, detect and report a multithreaded postmaster.
Darwin --enable-nls builds use a substitute setlocale() that may start athread. Buildfarm member orangutan experienced BackendList corruptionon account of different postmaster threads executing signal handlerssimultaneously. Furthermore, a multithreaded postmaster risks undefinedbehavior from sigprocmask() and fork(). Emit LOG messages about theproblem and its workaround. Back-patch to 9.0 (all supported versions).
1 parent05bb4fc commit8dc8310

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

‎configure

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19157,7 +19157,8 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
1915719157

1915819158

1915919159

19160-
for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l
19160+
19161+
for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l
1916119162
do
1916219163
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
1916319164
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5

‎configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ PGAC_FUNC_GETTIMEOFDAY_1ARG
12401240
LIBS_including_readline="$LIBS"
12411241
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
12421242

1243-
AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
1243+
AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstatpthread_is_threaded_npreadlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs wcstombs_l])
12441244

12451245
AC_REPLACE_FUNCS(fseeko)
12461246
case $host_os in

‎src/backend/postmaster/postmaster.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292
#include<dns_sd.h>
9393
#endif
9494

95+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
96+
#include<pthread.h>
97+
#endif
98+
9599
#include"access/transam.h"
96100
#include"access/xlog.h"
97101
#include"bootstrap/bootstrap.h"
@@ -1105,6 +1109,24 @@ PostmasterMain(int argc, char *argv[])
11051109
*/
11061110
RemovePgTempFiles();
11071111

1112+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1113+
1114+
/*
1115+
* On Darwin, libintl replaces setlocale() with a version that calls
1116+
* CFLocaleCopyCurrent() when its second argument is "" and every relevant
1117+
* environment variable is unset or empty. CFLocaleCopyCurrent() makes
1118+
* the process multithreaded. The postmaster calls sigprocmask() and
1119+
* calls fork() without an immediate exec(), both of which have undefined
1120+
* behavior in a multithreaded program. A multithreaded postmaster is the
1121+
* normal case on Windows, which offers neither fork() nor sigprocmask().
1122+
*/
1123+
if (pthread_is_threaded_np()!=0)
1124+
ereport(LOG,
1125+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1126+
errmsg("postmaster became multithreaded during startup"),
1127+
errhint("Set the LC_ALL environment variable to a valid locale.")));
1128+
#endif
1129+
11081130
/*
11091131
* Remember postmaster startup time
11101132
*/
@@ -1535,6 +1557,15 @@ ServerLoop(void)
15351557
TouchSocketLockFile();
15361558
last_touch_time=now;
15371559
}
1560+
1561+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1562+
1563+
/*
1564+
* With assertions enabled, check regularly for appearance of
1565+
* additional threads. All builds check at start and exit.
1566+
*/
1567+
Assert(pthread_is_threaded_np()==0);
1568+
#endif
15381569
}
15391570
}
15401571

@@ -4209,6 +4240,18 @@ SubPostmasterMain(int argc, char *argv[])
42094240
staticvoid
42104241
ExitPostmaster(intstatus)
42114242
{
4243+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
4244+
4245+
/*
4246+
* There is no known cause for a postmaster to become multithreaded after
4247+
* startup. Recheck to account for the possibility of unknown causes.
4248+
*/
4249+
if (pthread_is_threaded_np()!=0)
4250+
ereport(LOG,
4251+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4252+
errmsg("postmaster became multithreaded")));
4253+
#endif
4254+
42124255
/* should cleanup shared memory and kill all backends */
42134256

42144257
/*

‎src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@
393393
/* Define if you have POSIX threads libraries and header files. */
394394
#undef HAVE_PTHREAD
395395

396+
/* Define to 1 if you have the `pthread_is_threaded_np' function. */
397+
#undef HAVE_PTHREAD_IS_THREADED_NP
398+
396399
/* Define to 1 if you have the <pwd.h> header file. */
397400
#undef HAVE_PWD_H
398401

‎src/port/exec.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,20 @@ set_pglocale_pgservice(const char *argv0, const char *app)
570570

571571
/* don't set LC_ALL in the backend */
572572
if (strcmp(app,PG_TEXTDOMAIN("postgres"))!=0)
573+
{
573574
setlocale(LC_ALL,"");
574575

576+
/*
577+
* One could make a case for reproducing here PostmasterMain()'s test
578+
* for whether the process is multithreaded. Unlike the postmaster,
579+
* no frontend program calls sigprocmask() or otherwise provides for
580+
* mutual exclusion between signal handlers. While frontends using
581+
* fork(), if multithreaded, are formally exposed to undefined
582+
* behavior, we have not witnessed a concrete bug. Therefore,
583+
* complaining about multithreading here may be mere pedantry.
584+
*/
585+
}
586+
575587
if (find_my_exec(argv0,my_exec_path)<0)
576588
return;
577589

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp