|
87 | 87 | #include <dns_sd.h>
|
88 | 88 | #endif
|
89 | 89 |
|
| 90 | +#ifdef HAVE_PTHREAD_IS_THREADED_NP |
| 91 | +#include <pthread.h> |
| 92 | +#endif |
| 93 | + |
90 | 94 | #include "access/transam.h"
|
91 | 95 | #include "access/xlog.h"
|
92 | 96 | #include "bootstrap/bootstrap.h"
|
@@ -1203,6 +1207,24 @@ PostmasterMain(int argc, char *argv[])
|
1203 | 1207 | */
|
1204 | 1208 | RemovePgTempFiles();
|
1205 | 1209 |
|
| 1210 | +#ifdef HAVE_PTHREAD_IS_THREADED_NP |
| 1211 | + |
| 1212 | + /* |
| 1213 | + * On Darwin, libintl replaces setlocale() with a version that calls |
| 1214 | + * CFLocaleCopyCurrent() when its second argument is "" and every relevant |
| 1215 | + * environment variable is unset or empty. CFLocaleCopyCurrent() makes |
| 1216 | + * the process multithreaded. The postmaster calls sigprocmask() and |
| 1217 | + * calls fork() without an immediate exec(), both of which have undefined |
| 1218 | + * behavior in a multithreaded program. A multithreaded postmaster is the |
| 1219 | + * normal case on Windows, which offers neither fork() nor sigprocmask(). |
| 1220 | + */ |
| 1221 | + if (pthread_is_threaded_np() != 0) |
| 1222 | + ereport(LOG, |
| 1223 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 1224 | + errmsg("postmaster became multithreaded during startup"), |
| 1225 | + errhint("Set the LC_ALL environment variable to a valid locale."))); |
| 1226 | +#endif |
| 1227 | + |
1206 | 1228 | /*
|
1207 | 1229 | * Remember postmaster startup time
|
1208 | 1230 | */
|
@@ -1660,6 +1682,15 @@ ServerLoop(void)
|
1660 | 1682 | last_touch_time = now;
|
1661 | 1683 | }
|
1662 | 1684 |
|
| 1685 | +#ifdef HAVE_PTHREAD_IS_THREADED_NP |
| 1686 | + |
| 1687 | + /* |
| 1688 | + * With assertions enabled, check regularly for appearance of |
| 1689 | + * additional threads. All builds check at start and exit. |
| 1690 | + */ |
| 1691 | + Assert(pthread_is_threaded_np() == 0); |
| 1692 | +#endif |
| 1693 | + |
1663 | 1694 | /*
|
1664 | 1695 | * If we already sent SIGQUIT to children and they are slow to shut
|
1665 | 1696 | * down, it's time to send them SIGKILL. This doesn't happen
|
@@ -4738,6 +4769,18 @@ SubPostmasterMain(int argc, char *argv[])
|
4738 | 4769 | static void
|
4739 | 4770 | ExitPostmaster(int status)
|
4740 | 4771 | {
|
| 4772 | +#ifdef HAVE_PTHREAD_IS_THREADED_NP |
| 4773 | + |
| 4774 | + /* |
| 4775 | + * There is no known cause for a postmaster to become multithreaded after |
| 4776 | + * startup. Recheck to account for the possibility of unknown causes. |
| 4777 | + */ |
| 4778 | + if (pthread_is_threaded_np() != 0) |
| 4779 | + ereport(LOG, |
| 4780 | + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 4781 | + errmsg("postmaster became multithreaded"))); |
| 4782 | +#endif |
| 4783 | + |
4741 | 4784 | /* should cleanup shared memory and kill all backends */
|
4742 | 4785 |
|
4743 | 4786 | /*
|
|
0 commit comments