@@ -476,7 +476,7 @@ typedef struct
476
476
#endif /* WIN32 */
477
477
478
478
static 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 );
480
480
481
481
/* Type for a socket that can be inherited to a client process */
482
482
#ifdef WIN32
@@ -495,8 +495,13 @@ typedef int InheritableSocket;
495
495
*/
496
496
typedef struct
497
497
{
498
+ bool has_port ;
498
499
Port port ;
499
500
InheritableSocket portsocket ;
501
+
502
+ bool has_bgworker ;
503
+ BackgroundWorker bgworker ;
504
+
500
505
char DataDir [MAXPGPATH ];
501
506
int32 MyCancelKey ;
502
507
int MyPMChildSlot ;
@@ -542,13 +547,13 @@ typedef struct
542
547
char pkglib_path [MAXPGPATH ];
543
548
}BackendParameters ;
544
549
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 );
547
552
548
553
#ifndef WIN32
549
- static bool save_backend_variables (BackendParameters * param ,Port * port );
554
+ static bool save_backend_variables (BackendParameters * param ,Port * port , BackgroundWorker * worker );
550
555
#else
551
- static bool save_backend_variables (BackendParameters * param ,Port * port ,
556
+ static bool save_backend_variables (BackendParameters * param ,Port * port ,BackgroundWorker * worker ,
552
557
HANDLE childProcess ,pid_t childPid );
553
558
#endif
554
559
@@ -4441,11 +4446,7 @@ BackendRun(Port *port)
4441
4446
pid_t
4442
4447
postmaster_forkexec (int argc ,char * argv [])
4443
4448
{
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 );
4449
4450
}
4450
4451
4451
4452
/*
@@ -4470,7 +4471,7 @@ backend_forkexec(Port *port)
4470
4471
av [ac ]= NULL ;
4471
4472
Assert (ac < lengthof (av ));
4472
4473
4473
- return internal_forkexec (ac ,av ,port );
4474
+ return internal_forkexec (ac ,av ,port , NULL );
4474
4475
}
4475
4476
4476
4477
#ifndef WIN32
@@ -4482,7 +4483,7 @@ backend_forkexec(Port *port)
4482
4483
* - fork():s, and then exec():s the child process
4483
4484
*/
4484
4485
static pid_t
4485
- internal_forkexec (int argc ,char * argv [],Port * port )
4486
+ internal_forkexec (int argc ,char * argv [],Port * port , BackgroundWorker * worker )
4486
4487
{
4487
4488
static unsigned long tmpBackendFileNum = 0 ;
4488
4489
pid_t pid ;
@@ -4498,7 +4499,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
4498
4499
*/
4499
4500
memset (& param ,0 ,sizeof (BackendParameters ));
4500
4501
4501
- if (!save_backend_variables (& param ,port ))
4502
+ if (!save_backend_variables (& param ,port , worker ))
4502
4503
return -1 ;/* log made by save_backend_variables */
4503
4504
4504
4505
/* Calculate name for temp file */
@@ -4582,7 +4583,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
4582
4583
* file is complete.
4583
4584
*/
4584
4585
static pid_t
4585
- internal_forkexec (int argc ,char * argv [],Port * port )
4586
+ internal_forkexec (int argc ,char * argv [],Port * port , BackgroundWorker * worker )
4586
4587
{
4587
4588
int retry_count = 0 ;
4588
4589
STARTUPINFO si ;
@@ -4679,7 +4680,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
4679
4680
return -1 ;
4680
4681
}
4681
4682
4682
- if (!save_backend_variables (param ,port ,pi .hProcess ,pi .dwProcessId ))
4683
+ if (!save_backend_variables (param ,port ,worker , pi .hProcess ,pi .dwProcessId ))
4683
4684
{
4684
4685
/*
4685
4686
* 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)
4796
4797
void
4797
4798
SubPostmasterMain (int argc ,char * argv [])
4798
4799
{
4799
- Port port ;
4800
+ Port * port ;
4801
+ BackgroundWorker * worker ;
4800
4802
4801
4803
/* In EXEC_BACKEND case we will not have inherited these settings */
4802
4804
IsPostmasterEnvironment = true;
@@ -4810,8 +4812,7 @@ SubPostmasterMain(int argc, char *argv[])
4810
4812
elog (FATAL ,"invalid subpostmaster invocation" );
4811
4813
4812
4814
/* 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 );
4815
4816
4816
4817
/* Close the postmaster's sockets (as soon as we know them) */
4817
4818
ClosePostmasterPorts (strcmp (argv [1 ],"--forklog" )== 0 );
@@ -4839,7 +4840,7 @@ SubPostmasterMain(int argc, char *argv[])
4839
4840
strcmp (argv [1 ],"--forkavlauncher" )== 0 ||
4840
4841
strcmp (argv [1 ],"--forkavworker" )== 0 ||
4841
4842
strcmp (argv [1 ],"--forkaux" )== 0 ||
4842
- strncmp (argv [1 ],"--forkbgworker=" , 15 )== 0 )
4843
+ strcmp (argv [1 ],"--forkbgworker" )== 0 )
4843
4844
PGSharedMemoryReAttach ();
4844
4845
else
4845
4846
PGSharedMemoryNoReAttach ();
@@ -4912,7 +4913,7 @@ SubPostmasterMain(int argc, char *argv[])
4912
4913
* PGPROC slots, we have already initialized libpq and are able to
4913
4914
* report the error to the client.
4914
4915
*/
4915
- BackendInitialize (& port );
4916
+ BackendInitialize (port );
4916
4917
4917
4918
/* Restore basic shared memory pointers */
4918
4919
InitShmemAccess (UsedShmemSegAddr );
@@ -4924,7 +4925,7 @@ SubPostmasterMain(int argc, char *argv[])
4924
4925
AttachSharedMemoryStructs ();
4925
4926
4926
4927
/* And run the backend */
4927
- BackendRun (& port );/* does not return */
4928
+ BackendRun (port );/* does not return */
4928
4929
}
4929
4930
if (strcmp (argv [1 ],"--forkaux" )== 0 )
4930
4931
{
@@ -4970,10 +4971,8 @@ SubPostmasterMain(int argc, char *argv[])
4970
4971
4971
4972
AutoVacWorkerMain (argc - 2 ,argv + 2 );/* does not return */
4972
4973
}
4973
- if (strncmp (argv [1 ],"--forkbgworker=" , 15 )== 0 )
4974
+ if (strcmp (argv [1 ],"--forkbgworker" )== 0 )
4974
4975
{
4975
- int shmem_slot ;
4976
-
4977
4976
/* do this as early as possible; in particular, before InitProcess() */
4978
4977
IsBackgroundWorker = true;
4979
4978
@@ -4986,10 +4985,7 @@ SubPostmasterMain(int argc, char *argv[])
4986
4985
/* Attach process to shared data structures */
4987
4986
AttachSharedMemoryStructs ();
4988
4987
4989
- /* Fetch MyBgworkerEntry from shared memory */
4990
- shmem_slot = atoi (argv [1 ]+ 15 );
4991
- MyBgworkerEntry = BackgroundWorkerEntry (shmem_slot );
4992
-
4988
+ MyBgworkerEntry = worker ;
4993
4989
BackgroundWorkerMain ();
4994
4990
}
4995
4991
if (strcmp (argv [1 ],"--forklog" )== 0 )
@@ -5648,22 +5644,19 @@ BackgroundWorkerUnblockSignals(void)
5648
5644
5649
5645
#ifdef EXEC_BACKEND
5650
5646
static pid_t
5651
- bgworker_forkexec (int shmem_slot )
5647
+ bgworker_forkexec (BackgroundWorker * worker )
5652
5648
{
5653
5649
char * av [10 ];
5654
5650
int ac = 0 ;
5655
- char forkav [MAXPGPATH ];
5656
-
5657
- snprintf (forkav ,MAXPGPATH ,"--forkbgworker=%d" ,shmem_slot );
5658
5651
5659
5652
av [ac ++ ]= "postgres" ;
5660
- av [ac ++ ]= forkav ;
5661
- av [ac ++ ]= NULL ;/* filled in bypostmaster_forkexec */
5653
+ av [ac ++ ]= "--forkbgworker" ;
5654
+ av [ac ++ ]= NULL ;/* filled in byinternal_forkexec */
5662
5655
av [ac ]= NULL ;
5663
5656
5664
5657
Assert (ac < lengthof (av ));
5665
5658
5666
- return postmaster_forkexec (ac ,av );
5659
+ return internal_forkexec (ac ,av , NULL , worker );
5667
5660
}
5668
5661
#endif
5669
5662
@@ -5704,7 +5697,7 @@ do_start_bgworker(RegisteredBgWorker *rw)
5704
5697
rw -> rw_worker .bgw_name )));
5705
5698
5706
5699
#ifdef EXEC_BACKEND
5707
- switch ((worker_pid = bgworker_forkexec (rw -> rw_shmem_slot )))
5700
+ switch ((worker_pid = bgworker_forkexec (& rw -> rw_worker )))
5708
5701
#else
5709
5702
switch ((worker_pid = fork_process ()))
5710
5703
#endif
@@ -6037,16 +6030,36 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
6037
6030
/* Save critical backend variables into the BackendParameters struct */
6038
6031
#ifndef WIN32
6039
6032
static bool
6040
- save_backend_variables (BackendParameters * param ,Port * port )
6033
+ save_backend_variables (BackendParameters * param ,Port * port , BackgroundWorker * worker )
6041
6034
#else
6042
6035
static bool
6043
- save_backend_variables (BackendParameters * param ,Port * port ,
6036
+ save_backend_variables (BackendParameters * param ,Port * port ,BackgroundWorker * worker ,
6044
6037
HANDLE childProcess ,pid_t childPid )
6045
6038
#endif
6046
6039
{
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
+ }
6050
6063
6051
6064
strlcpy (param -> DataDir ,DataDir ,MAXPGPATH );
6052
6065
@@ -6202,7 +6215,7 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
6202
6215
#endif
6203
6216
6204
6217
static void
6205
- read_backend_variables (char * id ,Port * port )
6218
+ read_backend_variables (char * id ,Port * * port , BackgroundWorker * * worker )
6206
6219
{
6207
6220
BackendParameters param ;
6208
6221
@@ -6269,15 +6282,30 @@ read_backend_variables(char *id, Port *port)
6269
6282
}
6270
6283
#endif
6271
6284
6272
- restore_backend_variables (& param ,port );
6285
+ restore_backend_variables (& param ,port , worker );
6273
6286
}
6274
6287
6275
6288
/* Restore critical backend variables from the BackendParameters struct */
6276
6289
static void
6277
- restore_backend_variables (BackendParameters * param ,Port * port )
6290
+ restore_backend_variables (BackendParameters * param ,Port * * port , BackgroundWorker * * worker )
6278
6291
{
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 ;
6281
6309
6282
6310
SetDataDir (param -> DataDir );
6283
6311