@@ -476,7 +476,7 @@ typedef struct
476476#endif /* WIN32 */
477477
478478static pid_t backend_forkexec (Port * port );
479- static pid_t internal_forkexec (int argc , char * argv [], Port * port );
479+ static pid_t internal_forkexec (int argc , char * argv [], Port * port , BackgroundWorker * worker );
480480
481481/* Type for a socket that can be inherited to a client process */
482482#ifdef WIN32
@@ -495,8 +495,13 @@ typedef int InheritableSocket;
495495 */
496496typedef struct
497497{
498+ bool has_port ;
498499 Port port ;
499500 InheritableSocket portsocket ;
501+
502+ bool has_bgworker ;
503+ BackgroundWorker bgworker ;
504+
500505 char DataDir [MAXPGPATH ];
501506 int32 MyCancelKey ;
502507 int MyPMChildSlot ;
@@ -542,13 +547,13 @@ typedef struct
542547 char pkglib_path [MAXPGPATH ];
543548} BackendParameters ;
544549
545- static void read_backend_variables (char * id , Port * port );
546- static void restore_backend_variables (BackendParameters * param , Port * port );
550+ static void read_backend_variables (char * id , Port * * port , BackgroundWorker * * worker );
551+ static void restore_backend_variables (BackendParameters * param , Port * * port , BackgroundWorker * * worker );
547552
548553#ifndef WIN32
549- static bool save_backend_variables (BackendParameters * param , Port * port );
554+ static bool save_backend_variables (BackendParameters * param , Port * port , BackgroundWorker * worker );
550555#else
551- static bool save_backend_variables (BackendParameters * param , Port * port ,
556+ static bool save_backend_variables (BackendParameters * param , Port * port , BackgroundWorker * worker ,
552557 HANDLE childProcess , pid_t childPid );
553558#endif
554559
@@ -4441,11 +4446,7 @@ BackendRun(Port *port)
44414446pid_t
44424447postmaster_forkexec (int argc , char * argv [])
44434448{
4444- Port port ;
4445-
4446- /* This entry point passes dummy values for the Port variables */
4447- memset (& port , 0 , sizeof (port ));
4448- return internal_forkexec (argc , argv , & port );
4449+ return internal_forkexec (argc , argv , NULL , NULL );
44494450}
44504451
44514452/*
@@ -4470,7 +4471,7 @@ backend_forkexec(Port *port)
44704471 av [ac ] = NULL ;
44714472 Assert (ac < lengthof (av ));
44724473
4473- return internal_forkexec (ac , av , port );
4474+ return internal_forkexec (ac , av , port , NULL );
44744475}
44754476
44764477#ifndef WIN32
@@ -4482,7 +4483,7 @@ backend_forkexec(Port *port)
44824483 * - fork():s, and then exec():s the child process
44834484 */
44844485static pid_t
4485- internal_forkexec (int argc , char * argv [], Port * port )
4486+ internal_forkexec (int argc , char * argv [], Port * port , BackgroundWorker * worker )
44864487{
44874488 static unsigned long tmpBackendFileNum = 0 ;
44884489 pid_t pid ;
@@ -4498,7 +4499,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
44984499 */
44994500 memset (& param , 0 , sizeof (BackendParameters ));
45004501
4501- if (!save_backend_variables (& param , port ))
4502+ if (!save_backend_variables (& param , port , worker ))
45024503 return -1 ; /* log made by save_backend_variables */
45034504
45044505 /* Calculate name for temp file */
@@ -4582,7 +4583,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
45824583 * file is complete.
45834584 */
45844585static pid_t
4585- internal_forkexec (int argc , char * argv [], Port * port )
4586+ internal_forkexec (int argc , char * argv [], Port * port , BackgroundWorker * worker )
45864587{
45874588 int retry_count = 0 ;
45884589 STARTUPINFO si ;
@@ -4679,7 +4680,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
46794680 return -1 ;
46804681 }
46814682
4682- if (!save_backend_variables (param , port , pi .hProcess , pi .dwProcessId ))
4683+ if (!save_backend_variables (param , port , worker , pi .hProcess , pi .dwProcessId ))
46834684 {
46844685 /*
46854686 * log made by save_backend_variables, but we have to clean up the
@@ -4796,7 +4797,8 @@ internal_forkexec(int argc, char *argv[], Port *port)
47964797void
47974798SubPostmasterMain (int argc , char * argv [])
47984799{
4799- Port port ;
4800+ Port * port ;
4801+ BackgroundWorker * worker ;
48004802
48014803 /* In EXEC_BACKEND case we will not have inherited these settings */
48024804 IsPostmasterEnvironment = true;
@@ -4810,8 +4812,7 @@ SubPostmasterMain(int argc, char *argv[])
48104812 elog (FATAL , "invalid subpostmaster invocation" );
48114813
48124814 /* Read in the variables file */
4813- memset (& port , 0 , sizeof (Port ));
4814- read_backend_variables (argv [2 ], & port );
4815+ read_backend_variables (argv [2 ], & port , & worker );
48154816
48164817 /* Close the postmaster's sockets (as soon as we know them) */
48174818 ClosePostmasterPorts (strcmp (argv [1 ], "--forklog" ) == 0 );
@@ -4839,7 +4840,7 @@ SubPostmasterMain(int argc, char *argv[])
48394840 strcmp (argv [1 ], "--forkavlauncher" ) == 0 ||
48404841 strcmp (argv [1 ], "--forkavworker" ) == 0 ||
48414842 strcmp (argv [1 ], "--forkaux" ) == 0 ||
4842- strncmp (argv [1 ], "--forkbgworker=" , 15 ) == 0 )
4843+ strcmp (argv [1 ], "--forkbgworker" ) == 0 )
48434844 PGSharedMemoryReAttach ();
48444845 else
48454846 PGSharedMemoryNoReAttach ();
@@ -4912,7 +4913,7 @@ SubPostmasterMain(int argc, char *argv[])
49124913 * PGPROC slots, we have already initialized libpq and are able to
49134914 * report the error to the client.
49144915 */
4915- BackendInitialize (& port );
4916+ BackendInitialize (port );
49164917
49174918 /* Restore basic shared memory pointers */
49184919 InitShmemAccess (UsedShmemSegAddr );
@@ -4924,7 +4925,7 @@ SubPostmasterMain(int argc, char *argv[])
49244925 AttachSharedMemoryStructs ();
49254926
49264927 /* And run the backend */
4927- BackendRun (& port ); /* does not return */
4928+ BackendRun (port ); /* does not return */
49284929 }
49294930 if (strcmp (argv [1 ], "--forkaux" ) == 0 )
49304931 {
@@ -4970,10 +4971,8 @@ SubPostmasterMain(int argc, char *argv[])
49704971
49714972 AutoVacWorkerMain (argc - 2 , argv + 2 ); /* does not return */
49724973 }
4973- if (strncmp (argv [1 ], "--forkbgworker=" , 15 ) == 0 )
4974+ if (strcmp (argv [1 ], "--forkbgworker" ) == 0 )
49744975 {
4975- int shmem_slot ;
4976-
49774976 /* do this as early as possible; in particular, before InitProcess() */
49784977 IsBackgroundWorker = true;
49794978
@@ -4986,10 +4985,7 @@ SubPostmasterMain(int argc, char *argv[])
49864985 /* Attach process to shared data structures */
49874986 AttachSharedMemoryStructs ();
49884987
4989- /* Fetch MyBgworkerEntry from shared memory */
4990- shmem_slot = atoi (argv [1 ] + 15 );
4991- MyBgworkerEntry = BackgroundWorkerEntry (shmem_slot );
4992-
4988+ MyBgworkerEntry = worker ;
49934989 BackgroundWorkerMain ();
49944990 }
49954991 if (strcmp (argv [1 ], "--forklog" ) == 0 )
@@ -5648,22 +5644,19 @@ BackgroundWorkerUnblockSignals(void)
56485644
56495645#ifdef EXEC_BACKEND
56505646static pid_t
5651- bgworker_forkexec (int shmem_slot )
5647+ bgworker_forkexec (BackgroundWorker * worker )
56525648{
56535649 char * av [10 ];
56545650 int ac = 0 ;
5655- char forkav [MAXPGPATH ];
5656-
5657- snprintf (forkav , MAXPGPATH , "--forkbgworker=%d" , shmem_slot );
56585651
56595652 av [ac ++ ] = "postgres" ;
5660- av [ac ++ ] = forkav ;
5661- av [ac ++ ] = NULL ; /* filled in by postmaster_forkexec */
5653+ av [ac ++ ] = "--forkbgworker" ;
5654+ av [ac ++ ] = NULL ; /* filled in by internal_forkexec */
56625655 av [ac ] = NULL ;
56635656
56645657 Assert (ac < lengthof (av ));
56655658
5666- return postmaster_forkexec (ac , av );
5659+ return internal_forkexec (ac , av , NULL , worker );
56675660}
56685661#endif
56695662
@@ -5704,7 +5697,7 @@ do_start_bgworker(RegisteredBgWorker *rw)
57045697 rw -> rw_worker .bgw_name )));
57055698
57065699#ifdef EXEC_BACKEND
5707- switch ((worker_pid = bgworker_forkexec (rw -> rw_shmem_slot )))
5700+ switch ((worker_pid = bgworker_forkexec (& rw -> rw_worker )))
57085701#else
57095702 switch ((worker_pid = fork_process ()))
57105703#endif
@@ -6037,16 +6030,36 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
60376030/* Save critical backend variables into the BackendParameters struct */
60386031#ifndef WIN32
60396032static bool
6040- save_backend_variables (BackendParameters * param , Port * port )
6033+ save_backend_variables (BackendParameters * param , Port * port , BackgroundWorker * worker )
60416034#else
60426035static bool
6043- save_backend_variables (BackendParameters * param , Port * port ,
6036+ save_backend_variables (BackendParameters * param , Port * port , BackgroundWorker * worker ,
60446037 HANDLE childProcess , pid_t childPid )
60456038#endif
60466039{
6047- memcpy (& param -> port , port , sizeof (Port ));
6048- if (!write_inheritable_socket (& param -> portsocket , port -> sock , childPid ))
6049- return false;
6040+ if (port )
6041+ {
6042+ memcpy (& param -> port , port , sizeof (Port ));
6043+ if (!write_inheritable_socket (& param -> portsocket , port -> sock , childPid ))
6044+ return false;
6045+ param -> has_port = true;
6046+ }
6047+ else
6048+ {
6049+ memset (& param -> port , 0 , sizeof (Port ));
6050+ param -> has_port = false;
6051+ }
6052+
6053+ if (worker )
6054+ {
6055+ memcpy (& param -> bgworker , worker , sizeof (BackgroundWorker ));
6056+ param -> has_bgworker = true;
6057+ }
6058+ else
6059+ {
6060+ memset (& param -> bgworker , 0 , sizeof (BackgroundWorker ));
6061+ param -> has_bgworker = false;
6062+ }
60506063
60516064 strlcpy (param -> DataDir , DataDir , MAXPGPATH );
60526065
@@ -6202,7 +6215,7 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
62026215#endif
62036216
62046217static void
6205- read_backend_variables (char * id , Port * port )
6218+ read_backend_variables (char * id , Port * * port , BackgroundWorker * * worker )
62066219{
62076220 BackendParameters param ;
62086221
@@ -6269,15 +6282,30 @@ read_backend_variables(char *id, Port *port)
62696282 }
62706283#endif
62716284
6272- restore_backend_variables (& param , port );
6285+ restore_backend_variables (& param , port , worker );
62736286}
62746287
62756288/* Restore critical backend variables from the BackendParameters struct */
62766289static void
6277- restore_backend_variables (BackendParameters * param , Port * port )
6290+ restore_backend_variables (BackendParameters * param , Port * * port , BackgroundWorker * * worker )
62786291{
6279- memcpy (port , & param -> port , sizeof (Port ));
6280- read_inheritable_socket (& port -> sock , & param -> portsocket );
6292+ if (param -> has_port )
6293+ {
6294+ * port = (Port * ) MemoryContextAlloc (TopMemoryContext , sizeof (Port ));
6295+ memcpy (* port , & param -> port , sizeof (Port ));
6296+ read_inheritable_socket (& (* port )-> sock , & param -> portsocket );
6297+ }
6298+ else
6299+ * port = NULL ;
6300+
6301+ if (param -> has_bgworker )
6302+ {
6303+ * worker = (BackgroundWorker * )
6304+ MemoryContextAlloc (TopMemoryContext , sizeof (BackgroundWorker ));
6305+ memcpy (* worker , & param -> bgworker , sizeof (BackgroundWorker ));
6306+ }
6307+ else
6308+ * worker = NULL ;
62816309
62826310 SetDataDir (param -> DataDir );
62836311
0 commit comments