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

Commit1a366d5

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 parent230865e commit1a366d5

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

1983419834

1983519835

19836-
for ac_func in cbrt dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat readlink setproctitle setsid sigprocmask symlink sync_file_range towlower utime utimes wcstombs wcstombs_l
19836+
19837+
for ac_func in cbrt dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink setproctitle setsid sigprocmask symlink sync_file_range towlower utime utimes wcstombs wcstombs_l
1983719838
do
1983819839
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
1983919840
{ $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
@@ -1259,7 +1259,7 @@ PGAC_FUNC_GETTIMEOFDAY_1ARG
12591259
LIBS_including_readline="$LIBS"
12601260
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
12611261

1262-
AC_CHECK_FUNCS([cbrt dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat readlink setproctitle setsid sigprocmask symlink sync_file_range towlower utime utimes wcstombs wcstombs_l])
1262+
AC_CHECK_FUNCS([cbrt dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstatpthread_is_threaded_npreadlink setproctitle setsid sigprocmask symlink sync_file_range towlower utime utimes wcstombs wcstombs_l])
12631263

12641264
AC_REPLACE_FUNCS(fseeko)
12651265
case $host_os in

‎src/backend/postmaster/postmaster.c

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

94+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
95+
#include<pthread.h>
96+
#endif
97+
9498
#include"access/transam.h"
9599
#include"access/xlog.h"
96100
#include"bootstrap/bootstrap.h"
@@ -1233,6 +1237,24 @@ PostmasterMain(int argc, char *argv[])
12331237
*/
12341238
RemovePgTempFiles();
12351239

1240+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1241+
1242+
/*
1243+
* On Darwin, libintl replaces setlocale() with a version that calls
1244+
* CFLocaleCopyCurrent() when its second argument is "" and every relevant
1245+
* environment variable is unset or empty. CFLocaleCopyCurrent() makes
1246+
* the process multithreaded. The postmaster calls sigprocmask() and
1247+
* calls fork() without an immediate exec(), both of which have undefined
1248+
* behavior in a multithreaded program. A multithreaded postmaster is the
1249+
* normal case on Windows, which offers neither fork() nor sigprocmask().
1250+
*/
1251+
if (pthread_is_threaded_np()!=0)
1252+
ereport(LOG,
1253+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1254+
errmsg("postmaster became multithreaded during startup"),
1255+
errhint("Set the LC_ALL environment variable to a valid locale.")));
1256+
#endif
1257+
12361258
/*
12371259
* Remember postmaster startup time
12381260
*/
@@ -1675,6 +1697,15 @@ ServerLoop(void)
16751697
TouchSocketLockFiles();
16761698
last_touch_time=now;
16771699
}
1700+
1701+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
1702+
1703+
/*
1704+
* With assertions enabled, check regularly for appearance of
1705+
* additional threads. All builds check at start and exit.
1706+
*/
1707+
Assert(pthread_is_threaded_np()==0);
1708+
#endif
16781709
}
16791710
}
16801711

@@ -4632,6 +4663,18 @@ SubPostmasterMain(int argc, char *argv[])
46324663
staticvoid
46334664
ExitPostmaster(intstatus)
46344665
{
4666+
#ifdefHAVE_PTHREAD_IS_THREADED_NP
4667+
4668+
/*
4669+
* There is no known cause for a postmaster to become multithreaded after
4670+
* startup. Recheck to account for the possibility of unknown causes.
4671+
*/
4672+
if (pthread_is_threaded_np()!=0)
4673+
ereport(LOG,
4674+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4675+
errmsg("postmaster became multithreaded")));
4676+
#endif
4677+
46354678
/* should cleanup shared memory and kill all backends */
46364679

46374680
/*

‎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
@@ -556,8 +556,20 @@ set_pglocale_pgservice(const char *argv0, const char *app)
556556

557557
/* don't set LC_ALL in the backend */
558558
if (strcmp(app,PG_TEXTDOMAIN("postgres"))!=0)
559+
{
559560
setlocale(LC_ALL,"");
560561

562+
/*
563+
* One could make a case for reproducing here PostmasterMain()'s test
564+
* for whether the process is multithreaded. Unlike the postmaster,
565+
* no frontend program calls sigprocmask() or otherwise provides for
566+
* mutual exclusion between signal handlers. While frontends using
567+
* fork(), if multithreaded, are formally exposed to undefined
568+
* behavior, we have not witnessed a concrete bug. Therefore,
569+
* complaining about multithreading here may be mere pedantry.
570+
*/
571+
}
572+
561573
if (find_my_exec(argv0,my_exec_path)<0)
562574
return;
563575

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp