Pass MyPMChildSlot as an explicit argument to child process
authorHeikki Linnakangas <[email protected]>
Thu, 14 Nov 2024 14:12:32 +0000 (16:12 +0200)
committerHeikki Linnakangas <[email protected]>
Thu, 14 Nov 2024 14:12:32 +0000 (16:12 +0200)
All the other global variables passed from postmaster to child have
the same value in all the processes, while MyPMChildSlot is more like
a parameter to each child process.

Reviewed-by: Andres Freund <[email protected]>
Discussion: https://www.postgresql.org/message-id/a102f15f-eac4-4ff2-af02-f9ff209ec66f@iki.fi

src/backend/postmaster/launch_backend.c
src/backend/postmaster/postmaster.c
src/backend/postmaster/syslogger.c
src/include/postmaster/postmaster.h

index 6ce75f6f77d50062a63b8b0bbfc5295312098ddc..1f2d829ec5a657f81cd95f0e5704d3e8dd7e471f 100644 (file)
@@ -88,7 +88,6 @@ typedef int InheritableSocket;
 typedef struct
 {
    char        DataDir[MAXPGPATH];
-   int         MyPMChildSlot;
 #ifndef WIN32
    unsigned long UsedShmemSegID;
 #else
@@ -130,6 +129,8 @@ typedef struct
    char        my_exec_path[MAXPGPATH];
    char        pkglib_path[MAXPGPATH];
 
+   int         MyPMChildSlot;
+
    /*
     * These are only used by backend processes, but are here because passing
     * a socket needs some special handling on Windows. 'client_sock' is an
@@ -151,13 +152,16 @@ typedef struct
 static void read_backend_variables(char *id, char **startup_data, size_t *startup_data_len);
 static void restore_backend_variables(BackendParameters *param);
 
-static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock,
+static bool save_backend_variables(BackendParameters *param, int child_slot,
+                                  ClientSocket *client_sock,
 #ifdef WIN32
                                   HANDLE childProcess, pid_t childPid,
 #endif
                                   char *startup_data, size_t startup_data_len);
 
-static pid_t internal_forkexec(const char *child_kind, char *startup_data, size_t startup_data_len, ClientSocket *client_sock);
+static pid_t internal_forkexec(const char *child_kind, int child_slot,
+                              char *startup_data, size_t startup_data_len,
+                              ClientSocket *client_sock);
 
 #endif                         /* EXEC_BACKEND */
 
@@ -215,11 +219,12 @@ PostmasterChildName(BackendType child_type)
  * appropriate, and fds and other resources that we've inherited from
  * postmaster that are not needed in a child process have been closed.
  *
- * 'startup_data' is an optional contiguous chunk of data that is passed to
- * the child process.
+ * 'child_slot' is the PMChildFlags array index reserved for the child
+ * process.  'startup_data' is an optional contiguous chunk of data that is
+ * passed to the child process.
  */
 pid_t
-postmaster_child_launch(BackendType child_type,
+postmaster_child_launch(BackendType child_type, int child_slot,
                        char *startup_data, size_t startup_data_len,
                        ClientSocket *client_sock)
 {
@@ -228,7 +233,7 @@ postmaster_child_launch(BackendType child_type,
    Assert(IsPostmasterEnvironment && !IsUnderPostmaster);
 
 #ifdef EXEC_BACKEND
-   pid = internal_forkexec(child_process_kinds[child_type].name,
+   pid = internal_forkexec(child_process_kinds[child_type].name, child_slot,
                            startup_data, startup_data_len, client_sock);
    /* the child process will arrive in SubPostmasterMain */
 #else                          /* !EXEC_BACKEND */
@@ -256,6 +261,7 @@ postmaster_child_launch(BackendType child_type,
         */
        MemoryContextSwitchTo(TopMemoryContext);
 
+       MyPMChildSlot = child_slot;
        if (client_sock)
        {
            MyClientSocket = palloc(sizeof(ClientSocket));
@@ -282,7 +288,8 @@ postmaster_child_launch(BackendType child_type,
  * - fork():s, and then exec():s the child process
  */
 static pid_t
-internal_forkexec(const char *child_kind, char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
+internal_forkexec(const char *child_kind, int child_slot,
+                 char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
 {
    static unsigned long tmpBackendFileNum = 0;
    pid_t       pid;
@@ -302,7 +309,7 @@ internal_forkexec(const char *child_kind, char *startup_data, size_t startup_dat
     */
    paramsz = SizeOfBackendParameters(startup_data_len);
    param = palloc0(paramsz);
-   if (!save_backend_variables(param, client_sock, startup_data, startup_data_len))
+   if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
    {
        pfree(param);
        return -1;              /* log made by save_backend_variables */
@@ -391,7 +398,8 @@ internal_forkexec(const char *child_kind, char *startup_data, size_t startup_dat
  *  file is complete.
  */
 static pid_t
-internal_forkexec(const char *child_kind, char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
+internal_forkexec(const char *child_kind, int child_slot,
+                 char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
 {
    int         retry_count = 0;
    STARTUPINFO si;
@@ -472,7 +480,9 @@ retry:
        return -1;
    }
 
-   if (!save_backend_variables(param, client_sock, pi.hProcess, pi.dwProcessId, startup_data, startup_data_len))
+   if (!save_backend_variables(param, child_slot, client_sock,
+                               pi.hProcess, pi.dwProcessId,
+                               startup_data, startup_data_len))
    {
        /*
         * log made by save_backend_variables, but we have to clean up the
@@ -684,7 +694,8 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
 
 /* Save critical backend variables into the BackendParameters struct */
 static bool
-save_backend_variables(BackendParameters *param, ClientSocket *client_sock,
+save_backend_variables(BackendParameters *param,
+                      int child_slot, ClientSocket *client_sock,
 #ifdef WIN32
                       HANDLE childProcess, pid_t childPid,
 #endif
@@ -701,7 +712,7 @@ save_backend_variables(BackendParameters *param, ClientSocket *client_sock,
 
    strlcpy(param->DataDir, DataDir, MAXPGPATH);
 
-   param->MyPMChildSlot = MyPMChildSlot;
+   param->MyPMChildSlot = child_slot;
 
 #ifdef WIN32
    param->ShmemProtectiveRegion = ShmemProtectiveRegion;
index 4129c71efad488a8a15b1af0e78b8160e394ec1b..78e66a06ac5874161202fdd14ed76b263ffe3c2e 100644 (file)
@@ -3374,8 +3374,7 @@ BackendStartup(ClientSocket *client_sock)
    /* Hasn't asked to be notified about any bgworkers yet */
    bn->bgworker_notify = false;
 
-   MyPMChildSlot = bn->child_slot;
-   pid = postmaster_child_launch(bn->bkend_type,
+   pid = postmaster_child_launch(bn->bkend_type, bn->child_slot,
                                  (char *) &startup_data, sizeof(startup_data),
                                  client_sock);
    if (pid < 0)
@@ -3700,8 +3699,7 @@ StartChildProcess(BackendType type)
        return NULL;
    }
 
-   MyPMChildSlot = pmchild->child_slot;
-   pid = postmaster_child_launch(type, NULL, 0, NULL);
+   pid = postmaster_child_launch(type, pmchild->child_slot, NULL, 0, NULL);
    if (pid < 0)
    {
        /* in parent, fork failed */
@@ -3878,8 +3876,8 @@ StartBackgroundWorker(RegisteredBgWorker *rw)
            (errmsg_internal("starting background worker process \"%s\"",
                             rw->rw_worker.bgw_name)));
 
-   MyPMChildSlot = bn->child_slot;
-   worker_pid = postmaster_child_launch(B_BG_WORKER, (char *) &rw->rw_worker, sizeof(BackgroundWorker), NULL);
+   worker_pid = postmaster_child_launch(B_BG_WORKER, bn->child_slot,
+                                        (char *) &rw->rw_worker, sizeof(BackgroundWorker), NULL);
    if (worker_pid == -1)
    {
        /* in postmaster, fork failed ... */
index 7ca24c66634695d59aa4880b576ad31ffcf6177a..f12639056f2bfc7d462f08ee738ff7a163794c38 100644 (file)
@@ -694,14 +694,15 @@ SysLogger_Start(int child_slot)
        pfree(filename);
    }
 
-   MyPMChildSlot = child_slot;
 #ifdef EXEC_BACKEND
    startup_data.syslogFile = syslogger_fdget(syslogFile);
    startup_data.csvlogFile = syslogger_fdget(csvlogFile);
    startup_data.jsonlogFile = syslogger_fdget(jsonlogFile);
-   sysloggerPid = postmaster_child_launch(B_LOGGER, (char *) &startup_data, sizeof(startup_data), NULL);
+   sysloggerPid = postmaster_child_launch(B_LOGGER, child_slot,
+                                          (char *) &startup_data, sizeof(startup_data), NULL);
 #else
-   sysloggerPid = postmaster_child_launch(B_LOGGER, NULL, 0, NULL);
+   sysloggerPid = postmaster_child_launch(B_LOGGER, child_slot,
+                                          NULL, 0, NULL);
 #endif                         /* EXEC_BACKEND */
 
    if (sysloggerPid == -1)
index a55e7a79fa4ab822c64a1c7fecab3d70916b97a3..f05eb1c470b51757ca717adc83a7cf7bf9a08689 100644 (file)
@@ -108,6 +108,7 @@ extern PGDLLIMPORT struct ClientSocket *MyClientSocket;
 
 /* prototypes for functions in launch_backend.c */
 extern pid_t postmaster_child_launch(BackendType child_type,
+                                    int child_slot,
                                     char *startup_data,
                                     size_t startup_data_len,
                                     struct ClientSocket *client_sock);