@ -87,6 +87,10 @@
# include <dns_sd.h>
# endif
# ifdef HAVE_PTHREAD_IS_THREADED_NP
# include <pthread.h>
# endif
# include "access/transam.h"
# include "access/xlog.h"
# include "bootstrap/bootstrap.h"
@ -1200,6 +1204,24 @@ PostmasterMain(int argc, char *argv[])
*/
RemovePgTempFiles ( ) ;
# ifdef HAVE_PTHREAD_IS_THREADED_NP
/*
* On Darwin , libintl replaces setlocale ( ) with a version that calls
* CFLocaleCopyCurrent ( ) when its second argument is " " and every relevant
* environment variable is unset or empty . CFLocaleCopyCurrent ( ) makes
* the process multithreaded . The postmaster calls sigprocmask ( ) and
* calls fork ( ) without an immediate exec ( ) , both of which have undefined
* behavior in a multithreaded program . A multithreaded postmaster is the
* normal case on Windows , which offers neither fork ( ) nor sigprocmask ( ) .
*/
if ( pthread_is_threaded_np ( ) ! = 0 )
ereport ( LOG ,
( errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
errmsg ( " postmaster became multithreaded during startup " ) ,
errhint ( " Set the LC_ALL environment variable to a valid locale. " ) ) ) ;
# endif
/*
* Remember postmaster startup time
*/
@ -1657,6 +1679,15 @@ ServerLoop(void)
last_touch_time = now ;
}
# ifdef HAVE_PTHREAD_IS_THREADED_NP
/*
* With assertions enabled , check regularly for appearance of
* additional threads . All builds check at start and exit .
*/
Assert ( pthread_is_threaded_np ( ) = = 0 ) ;
# endif
/*
* If we already sent SIGQUIT to children and they are slow to shut
* down , it ' s time to send them SIGKILL . This doesn ' t happen
@ -4745,6 +4776,18 @@ SubPostmasterMain(int argc, char *argv[])
static void
ExitPostmaster ( int status )
{
# ifdef HAVE_PTHREAD_IS_THREADED_NP
/*
* There is no known cause for a postmaster to become multithreaded after
* startup . Recheck to account for the possibility of unknown causes .
*/
if ( pthread_is_threaded_np ( ) ! = 0 )
ereport ( LOG ,
( errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
errmsg ( " postmaster became multithreaded " ) ) ) ;
# endif
/* should cleanup shared memory and kill all backends */
/*