|
92 | 92 | #include <dns_sd.h>
|
93 | 93 | #endif
|
94 | 94 |
|
| 95 | +#ifdef HAVE_PTHREAD_IS_THREADED_NP |
| 96 | +#include <pthread.h> |
| 97 | +#endif |
| 98 | + |
95 | 99 | #include "access/transam.h"
|
96 | 100 | #include "access/xlog.h"
|
97 | 101 | #include "bootstrap/bootstrap.h"
|
@@ -1081,6 +1085,24 @@ PostmasterMain(int argc, char *argv[])
|
1081 | 1085 | }
|
1082 | 1086 | load_ident();
|
1083 | 1087 |
|
| 1088 | +#ifdef HAVE_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 | + |
1084 | 1106 | /*
|
1085 | 1107 | * Remember postmaster startup time
|
1086 | 1108 | */
|
@@ -1506,6 +1528,15 @@ ServerLoop(void)
|
1506 | 1528 | TouchSocketLockFile();
|
1507 | 1529 | last_touch_time = now;
|
1508 | 1530 | }
|
| 1531 | + |
| 1532 | +#ifdef HAVE_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 |
1509 | 1540 | }
|
1510 | 1541 | }
|
1511 | 1542 |
|
@@ -4155,6 +4186,18 @@ SubPostmasterMain(int argc, char *argv[])
|
4155 | 4186 | static void
|
4156 | 4187 | ExitPostmaster(int status)
|
4157 | 4188 | {
|
| 4189 | +#ifdef HAVE_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 | + |
4158 | 4201 | /* should cleanup shared memory and kill all backends */
|
4159 | 4202 |
|
4160 | 4203 | /*
|
|
0 commit comments