0008-Introduce-ClientSocket-rename-some-funcs.patch
text/x-patch
Filename: 0008-Introduce-ClientSocket-rename-some-funcs.patch
Type: text/x-patch
Part: 7
Message:
Refactoring backend fork+exec code
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0008
Subject: Introduce ClientSocket, rename some funcs
| File | + | − |
|---|---|---|
| src/backend/libpq/pqcomm.c | 49 | 44 |
| src/backend/postmaster/autovacuum.c | 4 | 4 |
| src/backend/postmaster/bgworker.c | 2 | 2 |
| src/backend/postmaster/postmaster.c | 76 | 63 |
| src/include/libpq/libpq-be.h | 13 | 6 |
| src/include/libpq/libpq.h | 3 | 3 |
From 65384b9a6cfb3b9b589041526216e0f64d64bea5 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Sun, 18 Jun 2023 13:56:44 +0300
Subject: [PATCH 8/9] Introduce ClientSocket, rename some funcs
- Move more of the work on a client socket to the child process.
- Reduce the amount of data that needs to be passed from postmaster to
child. (Used to pass a full Port struct, although most of the fields were
empty. Now we pass the much slimmer ClientSocket.)
---
src/backend/libpq/pqcomm.c | 93 ++++++++++---------
src/backend/postmaster/autovacuum.c | 8 +-
src/backend/postmaster/bgworker.c | 4 +-
src/backend/postmaster/postmaster.c | 139 +++++++++++++++-------------
src/include/libpq/libpq-be.h | 19 ++--
src/include/libpq/libpq.h | 6 +-
6 files changed, 147 insertions(+), 122 deletions(-)
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 9061daccc29..e2789cb4a4f 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -29,9 +29,9 @@
* INTERFACE ROUTINES
*
* setup/teardown:
- * StreamServerPort - Open postmaster's server port
- * StreamConnection - Create new connection with client
- * StreamClose - Close a client/backend connection
+ * ListenServerPort - Open postmaster's server port
+ * AcceptClientConnection - Create new connection with client
+ * StreamConnection - Initialize a client connection
* TouchSocketFiles - Protect socket files against /tmp cleaners
* pq_init - initialize libpq at backend startup
* socket_comm_reset - reset libpq during error recovery
@@ -304,7 +304,7 @@ socket_close(int code, Datum arg)
/*
- * StreamServerPort -- open a "listening" port to accept connections.
+ * ListenServerPort -- open a "listening" port to accept connections.
*
* family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
* For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
@@ -318,7 +318,7 @@ socket_close(int code, Datum arg)
*/
int
-StreamServerPort(int family, const char *hostName, unsigned short portNumber,
+ListenServerPort(int family, const char *hostName, unsigned short portNumber,
const char *unixSocketDir,
pgsocket ListenSocket[], int MaxListen)
{
@@ -689,8 +689,9 @@ Setup_AF_UNIX(const char *sock_path)
/*
- * StreamConnection -- create a new connection with client using
- * server port. Set port->sock to the FD of the new connection.
+ * AcceptClientConnection -- accept a new connection with client using
+ * server port. Fills *client_sock with the FD and endpoint info
+ * of the new connection.
*
* ASSUME: that this doesn't need to be non-blocking because
* the Postmaster waits for the socket to be ready to accept().
@@ -698,13 +699,13 @@ Setup_AF_UNIX(const char *sock_path)
* RETURNS: STATUS_OK or STATUS_ERROR
*/
int
-StreamConnection(pgsocket server_fd, Port *port)
+AcceptClientConnection(pgsocket server_fd, ClientSocket *client_sock)
{
/* accept connection and fill in the client (remote) address */
- port->raddr.salen = sizeof(port->raddr.addr);
- if ((port->sock = accept(server_fd,
- (struct sockaddr *) &port->raddr.addr,
- &port->raddr.salen)) == PGINVALID_SOCKET)
+ client_sock->raddr.salen = sizeof(client_sock->raddr.addr);
+ if ((client_sock->sock = accept(server_fd,
+ (struct sockaddr *) &client_sock->raddr.addr,
+ &client_sock->raddr.salen)) == PGINVALID_SOCKET)
{
ereport(LOG,
(errcode_for_socket_access(),
@@ -722,10 +723,10 @@ StreamConnection(pgsocket server_fd, Port *port)
}
/* fill in the server (local) address */
- port->laddr.salen = sizeof(port->laddr.addr);
- if (getsockname(port->sock,
- (struct sockaddr *) &port->laddr.addr,
- &port->laddr.salen) < 0)
+ client_sock->laddr.salen = sizeof(client_sock->laddr.addr);
+ if (getsockname(client_sock->sock,
+ (struct sockaddr *) &client_sock->laddr.addr,
+ &client_sock->laddr.salen) < 0)
{
ereport(LOG,
(errmsg("%s() failed: %m", "getsockname")));
@@ -733,7 +734,7 @@ StreamConnection(pgsocket server_fd, Port *port)
}
/* select NODELAY and KEEPALIVE options if it's a TCP connection */
- if (port->laddr.addr.ss_family != AF_UNIX)
+ if (client_sock->laddr.addr.ss_family != AF_UNIX)
{
int on;
#ifdef WIN32
@@ -744,7 +745,7 @@ StreamConnection(pgsocket server_fd, Port *port)
#ifdef TCP_NODELAY
on = 1;
- if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY,
+ if (setsockopt(client_sock->sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &on, sizeof(on)) < 0)
{
ereport(LOG,
@@ -753,7 +754,7 @@ StreamConnection(pgsocket server_fd, Port *port)
}
#endif
on = 1;
- if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE,
+ if (setsockopt(client_sock->sock, SOL_SOCKET, SO_KEEPALIVE,
(char *) &on, sizeof(on)) < 0)
{
ereport(LOG,
@@ -785,7 +786,7 @@ StreamConnection(pgsocket server_fd, Port *port)
* https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
*/
optlen = sizeof(oldopt);
- if (getsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt,
+ if (getsockopt(client_sock->sock, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt,
&optlen) < 0)
{
ereport(LOG,
@@ -795,7 +796,7 @@ StreamConnection(pgsocket server_fd, Port *port)
newopt = PQ_SEND_BUFFER_SIZE * 4;
if (oldopt < newopt)
{
- if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt,
+ if (setsockopt(client_sock->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt,
sizeof(newopt)) < 0)
{
ereport(LOG,
@@ -804,13 +805,34 @@ StreamConnection(pgsocket server_fd, Port *port)
}
}
#endif
+ }
+ return STATUS_OK;
+}
+
+/*
+ * StreamConnection -- create a new connection from the given socket.
+ *
+ * This runs in the backend process.
+ */
+Port *
+StreamConnection(ClientSocket *client_sock)
+{
+ Port *port;
+
+ port = palloc0(sizeof(Port));
+ port->sock = client_sock->sock;
+ port->laddr = client_sock->laddr;
+ port->raddr = client_sock->raddr;
+ /* Apply the current keepalive parameters if it's a TCP connection */
+ if (port->laddr.addr.ss_family != AF_UNIX)
+ {
/*
- * Also apply the current keepalive parameters. If we fail to set a
- * parameter, don't error out, because these aren't universally
- * supported. (Note: you might think we need to reset the GUC
- * variables to 0 in such a case, but it's not necessary because the
- * show hooks for these variables report the truth anyway.)
+ * If we fail to set a parameter, don't error out, because these
+ * aren't universally supported. (Note: you might think we need to
+ * reset the GUC variables to 0 in such a case, but it's not necessary
+ * because the show hooks for these variables report the truth
+ * anyway.)
*/
(void) pq_setkeepalivesidle(tcp_keepalives_idle, port);
(void) pq_setkeepalivesinterval(tcp_keepalives_interval, port);
@@ -818,24 +840,7 @@ StreamConnection(pgsocket server_fd, Port *port)
(void) pq_settcpusertimeout(tcp_user_timeout, port);
}
- return STATUS_OK;
-}
-
-/*
- * StreamClose -- close a client/backend connection
- *
- * NOTE: this is NOT used to terminate a session; it is just used to release
- * the file descriptor in a process that should no longer have the socket
- * open. (For example, the postmaster calls this after passing ownership
- * of the connection to a child process.) It is expected that someone else
- * still has the socket open. So, we only want to close the descriptor,
- * we do NOT want to send anything to the far end.
- */
-void
-StreamClose(pgsocket sock)
-{
- if (closesocket(sock) != 0)
- elog(LOG, "closesocket failed: %m");
+ return port;
}
/*
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 7157c5466aa..1041376951e 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -476,8 +476,8 @@ AutoVacLauncherMain(int argc, char *argv[])
pqsignal(SIGCHLD, SIG_DFL);
/*
- * Create a per-backend PGPROC struct in shared memory. We must do
- * this before we can use LWLocks.
+ * Create a per-backend PGPROC struct in shared memory. We must do this
+ * before we can use LWLocks.
*/
InitProcess();
@@ -1547,8 +1547,8 @@ AutoVacWorkerMain(int argc, char *argv[])
pqsignal(SIGCHLD, SIG_DFL);
/*
- * Create a per-backend PGPROC struct in shared memory. We must do
- * this before we can use LWLocks.
+ * Create a per-backend PGPROC struct in shared memory. We must do this
+ * before we can use LWLocks.
*/
InitProcess();
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 13519ea0c45..4c446ffd087 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -810,8 +810,8 @@ StartBackgroundWorker(void)
PG_exception_stack = &local_sigjmp_buf;
/*
- * Create a per-backend PGPROC struct in shared memory. We must do
- * this before we can use LWLocks.
+ * Create a per-backend PGPROC struct in shared memory. We must do this
+ * before we can use LWLocks.
*/
InitProcess();
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 8731b50e4a2..b73ba983f3e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -426,15 +426,15 @@ typedef enum CAC_state
CAC_TOOMANY
} CAC_state;
-static void BackendInitialize(Port *port, CAC_state cac);
-static void BackendRun(Port *port) pg_attribute_noreturn();
+static void BackendInitialize(ClientSocket *client_sock, CAC_state cac);
+static void BackendRun(void) pg_attribute_noreturn();
static void ExitPostmaster(int status) pg_attribute_noreturn();
static int ServerLoop(void);
-static int BackendStartup(Port *port);
+static int BackendStartup(ClientSocket *port);
static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done);
static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
static void processCancelRequest(Port *port, void *pkt);
-static void report_fork_failure_to_client(Port *port, int errnum);
+static void report_fork_failure_to_client(ClientSocket *client_sock, int errnum);
static CAC_state canAcceptConnections(int backend_type);
static bool RandomCancelKey(int32 *cancel_key);
static void signal_child(pid_t pid, int signal);
@@ -483,8 +483,8 @@ typedef struct
} win32_deadchild_waitinfo;
#endif /* WIN32 */
-static pid_t backend_forkexec(Port *port, CAC_state cac);
-static pid_t internal_forkexec(int argc, char *argv[], Port *port);
+static pid_t backend_forkexec(ClientSocket *client_sock, CAC_state cac);
+static pid_t internal_forkexec(int argc, char *argv[], ClientSocket *client_sock);
/* Type for a socket that can be inherited to a client process */
#ifdef WIN32
@@ -503,8 +503,8 @@ typedef int InheritableSocket;
*/
typedef struct
{
- Port port;
- InheritableSocket portsocket;
+ ClientSocket client_sock;
+ InheritableSocket serialized_sock;
char DataDir[MAXPGPATH];
int32 MyCancelKey;
int MyPMChildSlot;
@@ -552,13 +552,13 @@ typedef struct
BackgroundWorker MyBgworkerEntry;
} BackendParameters;
-static void read_backend_variables(char *id, Port *port);
-static void restore_backend_variables(BackendParameters *param, Port *port);
+static void read_backend_variables(char *id, ClientSocket *client_sock);
+static void restore_backend_variables(BackendParameters *param, ClientSocket *client_sock);
#ifndef WIN32
-static bool save_backend_variables(BackendParameters *param, Port *port);
+static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock);
#else
-static bool save_backend_variables(BackendParameters *param, Port *port,
+static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock,
HANDLE childProcess, pid_t childPid);
#endif
@@ -1221,12 +1221,12 @@ PostmasterMain(int argc, char *argv[])
char *curhost = (char *) lfirst(l);
if (strcmp(curhost, "*") == 0)
- status = StreamServerPort(AF_UNSPEC, NULL,
+ status = ListenServerPort(AF_UNSPEC, NULL,
(unsigned short) PostPortNumber,
NULL,
ListenSocket, MAXLISTEN);
else
- status = StreamServerPort(AF_UNSPEC, curhost,
+ status = ListenServerPort(AF_UNSPEC, curhost,
(unsigned short) PostPortNumber,
NULL,
ListenSocket, MAXLISTEN);
@@ -1318,7 +1318,7 @@ PostmasterMain(int argc, char *argv[])
{
char *socketdir = (char *) lfirst(l);
- status = StreamServerPort(AF_UNIX, NULL,
+ status = ListenServerPort(AF_UNIX, NULL,
(unsigned short) PostPortNumber,
socketdir,
ListenSocket, MAXLISTEN);
@@ -1499,7 +1499,7 @@ CloseServerPorts(int status, Datum arg)
{
if (ListenSocket[i] != PGINVALID_SOCKET)
{
- StreamClose(ListenSocket[i]);
+ closesocket(ListenSocket[i]);
ListenSocket[i] = PGINVALID_SOCKET;
}
}
@@ -1781,18 +1781,20 @@ ServerLoop(void)
if (events[i].events & WL_SOCKET_ACCEPT)
{
- Port port;
+ ClientSocket s;
- memset(&port, 0, sizeof(port));
- if (StreamConnection(events[i].fd, &port) == STATUS_OK)
- BackendStartup(&port);
+ if (AcceptClientConnection(events[i].fd, &s) == STATUS_OK)
+ BackendStartup(&s);
/*
* We no longer need the open socket or port structure in this
* process
*/
- if (port.sock != PGINVALID_SOCKET)
- StreamClose(port.sock);
+ if (s.sock != PGINVALID_SOCKET)
+ {
+ if (closesocket(s.sock) != 0)
+ elog(LOG, "could not close client socket: %m");
+ }
}
}
@@ -2529,7 +2531,8 @@ ClosePostmasterPorts(bool am_syslogger)
{
if (ListenSocket[i] != PGINVALID_SOCKET)
{
- StreamClose(ListenSocket[i]);
+ if (closesocket(ListenSocket[i]) != 0)
+ elog(LOG, "could not close listen socket: %m");
ListenSocket[i] = PGINVALID_SOCKET;
}
}
@@ -4034,7 +4037,7 @@ TerminateChildren(int signal)
* Note: if you change this code, also consider StartAutovacuumWorker.
*/
static int
-BackendStartup(Port *port)
+BackendStartup(ClientSocket *client_sock)
{
Backend *bn; /* for backend cleanup */
pid_t pid;
@@ -4085,7 +4088,7 @@ BackendStartup(Port *port)
bn->bgworker_notify = false;
#ifdef EXEC_BACKEND
- pid = backend_forkexec(port, cac);
+ pid = backend_forkexec(client_sock, cac);
#else /* !EXEC_BACKEND */
pid = fork_process();
if (pid == 0) /* child */
@@ -4097,10 +4100,10 @@ BackendStartup(Port *port)
ClosePostmasterPorts(false);
/* Perform additional initialization and collect startup packet */
- BackendInitialize(port, cac);
+ BackendInitialize(client_sock, cac);
/* And run the backend */
- BackendRun(port);
+ BackendRun();
}
#endif /* EXEC_BACKEND */
@@ -4115,14 +4118,14 @@ BackendStartup(Port *port)
errno = save_errno;
ereport(LOG,
(errmsg("could not fork new process for connection: %m")));
- report_fork_failure_to_client(port, save_errno);
+ report_fork_failure_to_client(client_sock, save_errno);
return STATUS_ERROR;
}
/* in parent, successful fork */
ereport(DEBUG2,
(errmsg_internal("forked new backend, pid=%d socket=%d",
- (int) pid, (int) port->sock)));
+ (int) pid, (int) client_sock->sock)));
/*
* Everything's been successful, it's safe to add this backend to our list
@@ -4149,7 +4152,7 @@ BackendStartup(Port *port)
* it's not up and running.
*/
static void
-report_fork_failure_to_client(Port *port, int errnum)
+report_fork_failure_to_client(ClientSocket *client_sock, int errnum)
{
char buffer[1000];
int rc;
@@ -4160,13 +4163,13 @@ report_fork_failure_to_client(Port *port, int errnum)
strerror(errnum));
/* Set port to non-blocking. Don't do send() if this fails */
- if (!pg_set_noblock(port->sock))
+ if (!pg_set_noblock(client_sock->sock))
return;
/* We'll retry after EINTR, but ignore all other failures */
do
{
- rc = send(port->sock, buffer, strlen(buffer) + 1, 0);
+ rc = send(client_sock->sock, buffer, strlen(buffer) + 1, 0);
} while (rc < 0 && errno == EINTR);
}
@@ -4184,16 +4187,24 @@ report_fork_failure_to_client(Port *port, int errnum)
* but have not yet set up most of our local pointers to shmem structures.
*/
static void
-BackendInitialize(Port *port, CAC_state cac)
+BackendInitialize(ClientSocket *client_sock, CAC_state cac)
{
int status;
int ret;
+ Port *port;
char remote_host[NI_MAXHOST];
char remote_port[NI_MAXSERV];
StringInfoData ps_data;
+ MemoryContext oldcontext;
- /* Save port etc. for ps status */
+ /*
+ * Create Port structure in TopMemoryContext, so that it survives into
+ * PostgresMain execution.
+ */
+ oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+ port = StreamConnection(client_sock);
MyProcPort = port;
+ MemoryContextSwitchTo(oldcontext);
/* Tell fd.c about the long-lived FD associated with the port */
ReserveExternalFD();
@@ -4254,8 +4265,9 @@ BackendInitialize(Port *port, CAC_state cac)
* Save remote_host and remote_port in port structure (after this, they
* will appear in log_line_prefix data for log messages).
*/
- port->remote_host = strdup(remote_host);
- port->remote_port = strdup(remote_port);
+ oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+ port->remote_host = pstrdup(remote_host);
+ port->remote_port = pstrdup(remote_port);
/* And now we can issue the Log_connections message, if wanted */
if (Log_connections)
@@ -4286,7 +4298,8 @@ BackendInitialize(Port *port, CAC_state cac)
ret == 0 &&
strspn(remote_host, "0123456789.") < strlen(remote_host) &&
strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host))
- port->remote_hostname = strdup(remote_host);
+ port->remote_hostname = pstrdup(remote_host);
+ MemoryContextSwitchTo(oldcontext);
/*
* Ready to begin client interaction. We will give up and _exit(1) after
@@ -4407,11 +4420,11 @@ BackendInitialize(Port *port, CAC_state cac)
* Doesn't return at all.
*/
static void
-BackendRun(Port *port)
+BackendRun(void)
{
/*
- * Create a per-backend PGPROC struct in shared memory. We must do
- * this before we can use LWLocks (in AttachSharedMemoryAndSemaphores).
+ * Create a per-backend PGPROC struct in shared memory. We must do this
+ * before we can use LWLocks (in AttachSharedMemoryAndSemaphores).
*/
InitProcess();
@@ -4424,7 +4437,7 @@ BackendRun(Port *port)
*/
MemoryContextSwitchTo(TopMemoryContext);
- PostgresMain(port->database_name, port->user_name);
+ PostgresMain(MyProcPort->database_name, MyProcPort->user_name);
}
@@ -4445,11 +4458,11 @@ BackendRun(Port *port)
pid_t
postmaster_forkexec(int argc, char *argv[])
{
- Port port;
+ ClientSocket client_sock;
- /* This entry point passes dummy values for the Port variables */
- memset(&port, 0, sizeof(port));
- return internal_forkexec(argc, argv, &port);
+ /* This entry point doesn't pass a client socket */
+ memset(&client_sock, 0, sizeof(ClientSocket));
+ return internal_forkexec(argc, argv, &client_sock);
}
/*
@@ -4462,7 +4475,7 @@ postmaster_forkexec(int argc, char *argv[])
* returns the pid of the fork/exec'd process, or -1 on failure
*/
static pid_t
-backend_forkexec(Port *port, CAC_state cac)
+backend_forkexec(ClientSocket *client_sock, CAC_state cac)
{
char *av[5];
int ac = 0;
@@ -4478,7 +4491,7 @@ backend_forkexec(Port *port, CAC_state cac)
av[ac] = NULL;
Assert(ac < lengthof(av));
- return internal_forkexec(ac, av, port);
+ return internal_forkexec(ac, av, client_sock);
}
#ifndef WIN32
@@ -4490,7 +4503,7 @@ backend_forkexec(Port *port, CAC_state cac)
* - fork():s, and then exec():s the child process
*/
static pid_t
-internal_forkexec(int argc, char *argv[], Port *port)
+internal_forkexec(int argc, char *argv[], ClientSocket *client_sock)
{
static unsigned long tmpBackendFileNum = 0;
pid_t pid;
@@ -4498,7 +4511,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
BackendParameters param;
FILE *fp;
- if (!save_backend_variables(¶m, port))
+ if (!save_backend_variables(¶m, client_sock))
return -1; /* log made by save_backend_variables */
/* Calculate name for temp file */
@@ -4796,7 +4809,7 @@ retry:
void
SubPostmasterMain(int argc, char *argv[])
{
- Port port;
+ ClientSocket client_sock;
/* In EXEC_BACKEND case we will not have inherited these settings */
IsPostmasterEnvironment = true;
@@ -4810,8 +4823,8 @@ SubPostmasterMain(int argc, char *argv[])
elog(FATAL, "invalid subpostmaster invocation");
/* Read in the variables file */
- memset(&port, 0, sizeof(Port));
- read_backend_variables(argv[2], &port);
+ memset(&client_sock, 0, sizeof(ClientSocket));
+ read_backend_variables(argv[2], &client_sock);
/* Close the postmaster's sockets (as soon as we know them) */
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
@@ -4915,13 +4928,13 @@ SubPostmasterMain(int argc, char *argv[])
* PGPROC slots, we have already initialized libpq and are able to
* report the error to the client.
*/
- BackendInitialize(&port, cac);
+ BackendInitialize(&client_sock, cac);
/* Restore basic shared memory pointers */
InitShmemAccess(UsedShmemSegAddr);
/* And run the backend */
- BackendRun(&port); /* does not return */
+ BackendRun(); /* does not return */
}
if (strcmp(argv[1], "--forkaux") == 0)
{
@@ -5995,15 +6008,15 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
/* Save critical backend variables into the BackendParameters struct */
#ifndef WIN32
static bool
-save_backend_variables(BackendParameters *param, Port *port)
+save_backend_variables(BackendParameters *param, ClientSocket *client_sock)
#else
static bool
-save_backend_variables(BackendParameters *param, Port *port,
+save_backend_variables(BackendParameters *param, ClientSocket *client_sock,
HANDLE childProcess, pid_t childPid)
#endif
{
- memcpy(¶m->port, port, sizeof(Port));
- if (!write_inheritable_socket(¶m->portsocket, port->sock, childPid))
+ memcpy(¶m->client_sock, client_sock, sizeof(ClientSocket));
+ if (!write_inheritable_socket(¶m->serialized_sock, client_sock->sock, childPid))
return false;
strlcpy(param->DataDir, DataDir, MAXPGPATH);
@@ -6165,7 +6178,7 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
#endif
static void
-read_backend_variables(char *id, Port *port)
+read_backend_variables(char *id, ClientSocket *client_sock)
{
BackendParameters param;
@@ -6232,15 +6245,15 @@ read_backend_variables(char *id, Port *port)
}
#endif
- restore_backend_variables(¶m, port);
+ restore_backend_variables(¶m, client_sock);
}
/* Restore critical backend variables from the BackendParameters struct */
static void
-restore_backend_variables(BackendParameters *param, Port *port)
+restore_backend_variables(BackendParameters *param, ClientSocket *client_sock)
{
- memcpy(port, ¶m->port, sizeof(Port));
- read_inheritable_socket(&port->sock, ¶m->portsocket);
+ memcpy(client_sock, ¶m->client_sock, sizeof(ClientSocket));
+ read_inheritable_socket(&client_sock->sock, ¶m->serialized_sock);
SetDataDir(param->DataDir);
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 625caa853a0..41867dc14ac 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -110,12 +110,9 @@ typedef struct ClientConnectionInfo
} ClientConnectionInfo;
/*
- * This is used by the postmaster in its communication with frontends. It
- * contains all state information needed during this communication before the
- * backend is run. The Port structure is kept in malloc'd memory and is
- * still available when a backend is running (see MyProcPort). The data
- * it points to must also be malloc'd, or else palloc'd in TopMemoryContext,
- * so that it survives into PostgresMain execution!
+ * The Port structure holds state information about a client connection in a
+ * backend process. It is available in the global variable MyProcPort. The
+ * struct and all the data it points are kept in TopMemoryContext.
*
* remote_hostname is set if we did a successful reverse lookup of the
* client's IP address during connection setup.
@@ -217,6 +214,16 @@ typedef struct Port
#endif
} Port;
+/*
+ * ClientSocket holds a socket for an accepted connection, along with the
+ * information about the endpoints.
+ */
+typedef struct ClientSocket {
+ pgsocket sock; /* File descriptor */
+ SockAddr laddr; /* local addr (postmaster) */
+ SockAddr raddr; /* remote addr (client) */
+} ClientSocket;
+
#ifdef USE_SSL
/*
* Hardcoded DH parameters, used in ephemeral DH keying. (See also
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 50fc781f471..fcbcdbe2dbf 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -64,11 +64,11 @@ extern PGDLLIMPORT WaitEventSet *FeBeWaitSet;
#define FeBeWaitSetLatchPos 1
#define FeBeWaitSetNEvents 3
-extern int StreamServerPort(int family, const char *hostName,
+extern int ListenServerPort(int family, const char *hostName,
unsigned short portNumber, const char *unixSocketDir,
pgsocket ListenSocket[], int MaxListen);
-extern int StreamConnection(pgsocket server_fd, Port *port);
-extern void StreamClose(pgsocket sock);
+extern int AcceptClientConnection(pgsocket server_fd, ClientSocket *client_sock);
+extern Port *StreamConnection(ClientSocket *client_sock);
extern void TouchSocketFiles(void);
extern void RemoveSocketFiles(void);
extern void pq_init(void);
--
2.30.2