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

Commit2e49461

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 parent3580397 commit2e49461

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
@@ -18839,7 +18839,8 @@ LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
1883918839

1884018840

1884118841

18842-
for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeereid getpeerucred getrlimit memmove poll pstat readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs
18842+
18843+
for ac_func in cbrt dlopen fcvt fdatasync getifaddrs getpeereid getpeerucred getrlimit memmove poll pstat pthread_is_threaded_np readlink scandir setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs
1884318844
do
1884418845
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
1884518846
{ $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
@@ -1210,7 +1210,7 @@ PGAC_FUNC_GETTIMEOFDAY_1ARG
12101210
LIBS_including_readline="$LIBS"
12111211
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
12121212

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

12151215
AC_REPLACE_FUNCS(fseeko)
12161216
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"
@@ -1081,6 +1085,24 @@ PostmasterMain(int argc, char *argv[])
10811085
}
10821086
load_ident();
10831087

1088+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1089+
1090+
/*
1091+
* On Darwin, libintl replaces setlocale() with a version that calls
1092+
* CFLocaleCopyCurrent() when its second argument is "" and every relevant
1093+
* environment variable is unset or empty. CFLocaleCopyCurrent() makes
1094+
* the process multithreaded. The postmaster calls sigprocmask() and
1095+
* calls fork() without an immediate exec(), both of which have undefined
1096+
* behavior in a multithreaded program. A multithreaded postmaster is the
1097+
* normal case on Windows, which offers neither fork() nor sigprocmask().
1098+
*/
1099+
if (pthread_is_threaded_np()!=0)
1100+
ereport(LOG,
1101+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1102+
errmsg("postmaster became multithreaded during startup"),
1103+
errhint("Set the LC_ALL environment variable to a valid locale.")));
1104+
#endif
1105+
10841106
/*
10851107
* Remember postmaster startup time
10861108
*/
@@ -1506,6 +1528,15 @@ ServerLoop(void)
15061528
TouchSocketLockFile();
15071529
last_touch_time=now;
15081530
}
1531+
1532+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1533+
1534+
/*
1535+
* With assertions enabled, check regularly for appearance of
1536+
* additional threads. All builds check at start and exit.
1537+
*/
1538+
Assert(pthread_is_threaded_np()==0);
1539+
#endif
15091540
}
15101541
}
15111542

@@ -4155,6 +4186,18 @@ SubPostmasterMain(int argc, char *argv[])
41554186
staticvoid
41564187
ExitPostmaster(intstatus)
41574188
{
4189+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
4190+
4191+
/*
4192+
* There is no known cause for a postmaster to become multithreaded after
4193+
* startup. Recheck to account for the possibility of unknown causes.
4194+
*/
4195+
if (pthread_is_threaded_np()!=0)
4196+
ereport(LOG,
4197+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4198+
errmsg("postmaster became multithreaded")));
4199+
#endif
4200+
41584201
/* should cleanup shared memory and kill all backends */
41594202

41604203
/*

‎src/include/pg_config.h.in

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

390+
/* Define to 1 if you have the `pthread_is_threaded_np' function. */
391+
#undef HAVE_PTHREAD_IS_THREADED_NP
392+
390393
/* Define to 1 if you have the <pwd.h> header file. */
391394
#undef HAVE_PWD_H
392395

‎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