From 0bce567e279e88e868a2b23f3905fa0de2e26eb9 Mon Sep 17 00:00:00 2001
From: Mike Palmiotto <mike.palmiotto@crunchydata.com>
Date: Wed, 4 Mar 2020 04:41:18 +0000
Subject: [PATCH 11/11] Use MyProcPort instead of adding ConnProcPort

We still need to handle the edge-case of no backend variables being
inherited. In the case where MyProcPort is not obtained from the backend
variables, just create a dummy port so we can proceed with the forkexec.
---
 src/backend/postmaster/postmaster.c | 53 ++++++++++++++++-------------
 1 file changed, 30 insertions(+), 23 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 06622d3acb..17a5c3d26c 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -412,7 +412,7 @@ typedef struct
 } win32_deadchild_waitinfo;
 #endif							/* WIN32 */
 
-static pid_t internal_forkexec(int argc, char *argv[]);
+static pid_t internal_forkexec(int argc, char *argv[], Port *port);
 
 /* Type for a socket that can be inherited to a client process */
 #ifdef WIN32
@@ -514,8 +514,6 @@ int			postmaster_alive_fds[2] = {-1, -1};
 HANDLE		PostmasterHandle;
 #endif
 
-static Port *ConnProcPort = NULL;
-
 /*
  * Postmaster main entry point
  */
@@ -1675,17 +1673,20 @@ ServerLoop(void)
 					break;
 				if (FD_ISSET(ListenSocket[i], &rmask))
 				{
-					ConnProcPort = ConnCreate(ListenSocket[i]);
-					if (ConnProcPort)
+					Port	*port;
+
+					port= ConnCreate(ListenSocket[i]);
+					if (port)
 					{
+						MyProcPort = port;
 						StartSubprocess(ClientBackendType);
 
 						/*
 						 * We no longer need the open socket or port structure
 						 * in this process
 						 */
-						StreamClose(ConnProcPort->sock);
-						ConnFree(ConnProcPort);
+						StreamClose(port->sock);
+						ConnFree(port);
 					}
 				}
 			}
@@ -3248,9 +3249,9 @@ BackendPrep(int argc, char *argv[])
 	bn->cancel_key = MyCancelKey;
 
 	/* Pass down canAcceptConnections state */
-	ConnProcPort->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
-	bn->dead_end = (ConnProcPort->canAcceptConnections != CAC_OK &&
-						   ConnProcPort->canAcceptConnections != CAC_WAITBACKUP);
+	MyProcPort->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
+	bn->dead_end = (MyProcPort->canAcceptConnections != CAC_OK &&
+						   MyProcPort->canAcceptConnections != CAC_WAITBACKUP);
 
 	/*
 	 * Unless it's a dead_end child, assign it a child slot number
@@ -3288,10 +3289,10 @@ void BackendMain(pg_attribute_unused() int argc, pg_attribute_unused() char *arg
 	 * PGPROC slots, we have already initialized libpq and are able to
 	 * report the error to the client.
 	 */
-	BackendInitialize(ConnProcPort);
+	BackendInitialize(MyProcPort);
 
 	/* And run the backend */
-	BackendRun(ConnProcPort);		/* does not return */
+	BackendRun(MyProcPort);		/* does not return */
 }
 
 /*
@@ -4528,11 +4529,19 @@ BackendRun(Port *port)
 pid_t
 postmaster_forkexec(int argc, char *argv[])
 {
-	/* This entry point passes dummy values for the Port variables */
-	if (!ConnProcPort)
-		ConnProcPort = palloc0(sizeof(*ConnProcPort));
+	Port	port;
+
+	/*
+	 * When there are no backend variables to inherit (i.e. checker process),
+	 * MyProcPort will be empty.  Create a dummy variable to pass along to
+	 * satisfy this case. Otherwise just use MyProcPort.
+	 */
+	if (!MyProcPort)
+		memset(&port, 0, sizeof(port));
+	else
+		port = *MyProcPort;
 
-	return internal_forkexec(argc, argv);
+	return internal_forkexec(argc, argv, &port);
 }
 
 #ifndef WIN32
@@ -4544,7 +4553,7 @@ postmaster_forkexec(int argc, char *argv[])
  * - fork():s, and then exec():s the child process
  */
 static pid_t
-internal_forkexec(int argc, char *argv[])
+internal_forkexec(int argc, char *argv[], Port *port)
 {
 	static unsigned long tmpBackendFileNum = 0;
 	pid_t		pid;
@@ -4552,7 +4561,7 @@ internal_forkexec(int argc, char *argv[])
 	BackendParameters param;
 	FILE	   *fp;
 
-	if (!save_backend_variables(&param, ConnProcPort))
+	if (!save_backend_variables(&param, port))
 		return -1;				/* log made by save_backend_variables */
 
 	/* Calculate name for temp file */
@@ -4891,12 +4900,10 @@ SubPostmasterMain(int argc, char *argv[])
 	if (argc < 3)
 		elog(FATAL, "invalid subpostmaster invocation");
 
-	Assert(!ConnProcPort);
-
 	/* Read in the variables file */
 	memset(&port, 0, sizeof(Port));
 	read_backend_variables(argv[2], &port);
-	ConnProcPort = &port;
+	MyProcPort = &port;
 
 	/* Close the postmaster's sockets (as soon as we know them) */
 	ClosePostmasterPorts();
@@ -5023,12 +5030,12 @@ SubPostmasterMain(int argc, char *argv[])
 		 * PGPROC slots, we have already initialized libpq and are able to
 		 * report the error to the client.
 		 */
-		BackendInitialize(&port);
+		BackendInitialize(MyProcPort);
 
 		shmemSetup();
 
 		/* And run the backend */
-		BackendRun(&port);		/* does not return */
+		BackendRun(MyProcPort);		/* does not return */
 	}
 
 	/* do this as early as possible; in particular, before InitProcess() */
-- 
2.21.0

