diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index f091ec74212957b315317aad187022434c488849..aff9a5e1159a788f427d24747fbb047c441089ff 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -338,6 +338,7 @@ static DNSServiceRef bonjour_sdref = NULL; /* * postmaster.c - function prototypes */ +static void CloseServerPorts(int status, Datum arg); static void getInstallationPaths(const char *argv0); static void checkDataDir(void); static Port *ConnCreate(int serverFd); @@ -991,6 +992,14 @@ PostmasterMain(int argc, char *argv[]) ereport(FATAL, (errmsg("no socket created for listening"))); + /* + * Set up an on_proc_exit function that's charged with closing the sockets + * again at postmaster shutdown. You might think we should have done this + * earlier, but we want it to run before not after the proc_exit callback + * that will remove the Unix socket file. + */ + on_proc_exit(CloseServerPorts, 0); + /* * If no valid TCP ports, write an empty line for listen address, * indicating the Unix socket must be used. Note that this line is not @@ -1161,6 +1170,36 @@ PostmasterMain(int argc, char *argv[]) } +/* + * on_proc_exit callback to close server's listen sockets + */ +static void +CloseServerPorts(int status, Datum arg) +{ + int i; + + /* + * First, explicitly close all the socket FDs. We used to just let this + * happen implicitly at postmaster exit, but it's better to close them + * before we remove the postmaster.pid lockfile; otherwise there's a race + * condition if a new postmaster wants to re-use the TCP port number. + */ + for (i = 0; i < MAXLISTEN; i++) + { + if (ListenSocket[i] != PGINVALID_SOCKET) + { + StreamClose(ListenSocket[i]); + ListenSocket[i] = PGINVALID_SOCKET; + } + } + + /* + * Removal of the Unix socket file and socket lockfile will happen in + * later on_proc_exit callbacks. + */ +} + + /* * Compute and check the directory paths to files that are part of the * installation (as deduced from the postgres executable's own location)