From f871e915fee08b3cc27e732646f3a62ec1c3024b Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 29 Feb 2024 23:20:52 +0200 Subject: [PATCH 1/2] Move cancel key generation to after forking the backend Move responsibility of generating the cancel key to the backend process. The cancel key is now generated after forking, and the backend advertises it in the PMSignalState array. When a cancel request arrives, the backend handling it scans the PMSignalState array to find the target pid and cancel key. This is similar to how this previously worked in the EXEC_BACKEND case with the ShmemBackendArray, but instead of having the separate array, we store the cancel keys in PMSignalState array, and use it also in the !EXEC_BACKEND case. While we're at it, switch to using atomics in pmsignal.c for the state field. That feels easier to reason about than volatile pointers. (TODO: also switch to pg_atomic_flag for PMSignalFlags array. Weirdly we don't have "pg_atomic_test_clear_flag" nor "pg_atomic_set_flag". Those would be the natural opertions for PMSignalFlags. Maybe we should add those, but I didn't want to go that deep down the rabbit hole in this patch.) This is needed by the next patch, so that we can generate the cancel key later, after negotiating the protocol version with the client. --- src/backend/postmaster/postmaster.c | 185 +--------------------------- src/backend/storage/ipc/ipci.c | 11 -- src/backend/storage/ipc/pmsignal.c | 124 ++++++++++++++----- src/backend/storage/lmgr/proc.c | 16 ++- src/include/postmaster/postmaster.h | 3 - src/include/storage/pmsignal.h | 3 +- src/tools/pgindent/typedefs.list | 1 + 7 files changed, 116 insertions(+), 227 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index da0c627107e..408f8fb9b6d 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -177,7 +177,6 @@ typedef struct bkend { pid_t pid; /* process id of backend */ - int32 cancel_key; /* cancel key for cancels for this backend */ int child_slot; /* PMChildSlot for this backend, if any */ int bkend_type; /* child process flavor, see above */ bool dead_end; /* is it going to send an error and quit? */ @@ -187,10 +186,6 @@ typedef struct bkend static dlist_head BackendList = DLIST_STATIC_INIT(BackendList); -#ifdef EXEC_BACKEND -static Backend *ShmemBackendArray; -#endif - BackgroundWorker *MyBgworkerEntry = NULL; @@ -430,7 +425,6 @@ 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 CAC_state canAcceptConnections(int backend_type); -static bool RandomCancelKey(int32 *cancel_key); static void signal_child(pid_t pid, int signal); static void sigquit_child(pid_t pid); static bool SignalSomeChildren(int signal, int target); @@ -517,7 +511,6 @@ typedef struct #endif void *UsedShmemSegAddr; slock_t *ShmemLock; - Backend *ShmemBackendArray; #ifndef HAVE_SPINLOCKS PGSemaphore *SpinlockSemaArray; #endif @@ -559,9 +552,6 @@ static bool save_backend_variables(BackendParameters *param, Port *port, Backgro static bool save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker, HANDLE childProcess, pid_t childPid); #endif - -static void ShmemBackendArrayAdd(Backend *bn); -static void ShmemBackendArrayRemove(Backend *bn); #endif /* EXEC_BACKEND */ /* Macros to check exit status of a child process */ @@ -2334,58 +2324,11 @@ processCancelRequest(Port *port, void *pkt) CancelRequestPacket *canc = (CancelRequestPacket *) pkt; int backendPID; int32 cancelAuthCode; - Backend *bp; - -#ifndef EXEC_BACKEND - dlist_iter iter; -#else - int i; -#endif backendPID = (int) pg_ntoh32(canc->backendPID); cancelAuthCode = (int32) pg_ntoh32(canc->cancelAuthCode); - /* - * See if we have a matching backend. In the EXEC_BACKEND case, we can no - * longer access the postmaster's own backend list, and must rely on the - * duplicate array in shared memory. - */ -#ifndef EXEC_BACKEND - dlist_foreach(iter, &BackendList) - { - bp = dlist_container(Backend, elem, iter.cur); -#else - for (i = MaxLivePostmasterChildren() - 1; i >= 0; i--) - { - bp = (Backend *) &ShmemBackendArray[i]; -#endif - if (bp->pid == backendPID) - { - if (bp->cancel_key == cancelAuthCode) - { - /* Found a match; signal that backend to cancel current op */ - ereport(DEBUG2, - (errmsg_internal("processing cancel request: sending SIGINT to process %d", - backendPID))); - signal_child(bp->pid, SIGINT); - } - else - /* Right PID, wrong key: no way, Jose */ - ereport(LOG, - (errmsg("wrong key in cancel request for process %d", - backendPID))); - return; - } -#ifndef EXEC_BACKEND /* make GNU Emacs 26.1 see brace balance */ - } -#else - } -#endif - - /* No matching backend */ - ereport(LOG, - (errmsg("PID %d in cancel request did not match any process", - backendPID))); + SendCancelRequest(backendPID, cancelAuthCode); } /* @@ -3296,9 +3239,6 @@ CleanupBackgroundWorker(int pid, /* Get it out of the BackendList and clear out remaining data */ dlist_delete(&rw->rw_backend->elem); -#ifdef EXEC_BACKEND - ShmemBackendArrayRemove(rw->rw_backend); -#endif /* * It's possible that this background worker started some OTHER @@ -3384,9 +3324,6 @@ CleanupBackend(int pid, HandleChildCrash(pid, exitstatus, _("server process")); return; } -#ifdef EXEC_BACKEND - ShmemBackendArrayRemove(bp); -#endif } if (bp->bgworker_notify) { @@ -3454,9 +3391,6 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) */ (void) ReleasePostmasterChildSlot(rw->rw_child_slot); dlist_delete(&rw->rw_backend->elem); -#ifdef EXEC_BACKEND - ShmemBackendArrayRemove(rw->rw_backend); -#endif pfree(rw->rw_backend); rw->rw_backend = NULL; rw->rw_pid = 0; @@ -3489,9 +3423,6 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) if (!bp->dead_end) { (void) ReleasePostmasterChildSlot(bp->child_slot); -#ifdef EXEC_BACKEND - ShmemBackendArrayRemove(bp); -#endif } dlist_delete(iter.cur); pfree(bp); @@ -4103,22 +4034,6 @@ BackendStartup(Port *port) return STATUS_ERROR; } - /* - * Compute the cancel key that will be assigned to this backend. The - * backend will have its own copy in the forked-off process' value of - * MyCancelKey, so that it can transmit the key to the frontend. - */ - if (!RandomCancelKey(&MyCancelKey)) - { - pfree(bn); - ereport(LOG, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("could not generate random cancel key"))); - return STATUS_ERROR; - } - - bn->cancel_key = MyCancelKey; - /* Pass down canAcceptConnections state */ port->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL); bn->dead_end = (port->canAcceptConnections != CAC_OK); @@ -4182,11 +4097,6 @@ BackendStartup(Port *port) bn->bkend_type = BACKEND_TYPE_NORMAL; /* Can change later to WALSND */ dlist_push_head(&BackendList, &bn->elem); -#ifdef EXEC_BACKEND - if (!bn->dead_end) - ShmemBackendArrayAdd(bn); -#endif - return STATUS_OK; } @@ -5252,16 +5162,6 @@ StartupPacketTimeoutHandler(void) _exit(1); } - -/* - * Generate a random cancel key. - */ -static bool -RandomCancelKey(int32 *cancel_key) -{ - return pg_strong_random(cancel_key, sizeof(int32)); -} - /* * Count up number of child processes of specified types (dead_end children * are always excluded). @@ -5437,25 +5337,9 @@ StartAutovacuumWorker(void) */ if (canAcceptConnections(BACKEND_TYPE_AUTOVAC) == CAC_OK) { - /* - * Compute the cancel key that will be assigned to this session. We - * probably don't need cancel keys for autovac workers, but we'd - * better have something random in the field to prevent unfriendly - * people from sending cancels to them. - */ - if (!RandomCancelKey(&MyCancelKey)) - { - ereport(LOG, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("could not generate random cancel key"))); - return; - } - bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM); if (bn) { - bn->cancel_key = MyCancelKey; - /* Autovac workers are not dead_end and need a child slot */ bn->dead_end = false; bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot(); @@ -5466,9 +5350,6 @@ StartAutovacuumWorker(void) { bn->bkend_type = BACKEND_TYPE_AUTOVAC; dlist_push_head(&BackendList, &bn->elem); -#ifdef EXEC_BACKEND - ShmemBackendArrayAdd(bn); -#endif /* all OK */ return; } @@ -5600,11 +5481,10 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname) /* * MaxLivePostmasterChildren * - * This reports the number of entries needed in per-child-process arrays - * (the PMChildFlags array, and if EXEC_BACKEND the ShmemBackendArray). - * These arrays include regular backends, autovac workers, walsenders + * This reports the number of entries needed in the per-child-process array. + * The array includes regular backends, autovac workers, walsenders * and background workers, but not special children nor dead_end children. - * This allows the arrays to have a fixed maximum size, to wit the same + * This allows the array to have a fixed maximum size, to wit the same * too-many-children limit enforced by canAcceptConnections(). The exact value * isn't too critical as long as it's more than MaxBackends. */ @@ -5804,9 +5684,6 @@ do_start_bgworker(RegisteredBgWorker *rw) ReportBackgroundWorkerPID(rw); /* add new worker to lists of backends */ dlist_push_head(&BackendList, &rw->rw_backend->elem); -#ifdef EXEC_BACKEND - ShmemBackendArrayAdd(rw->rw_backend); -#endif return true; } @@ -5877,20 +5754,6 @@ assign_backendlist_entry(RegisteredBgWorker *rw) return false; } - /* - * Compute the cancel key that will be assigned to this session. We - * probably don't need cancel keys for background workers, but we'd better - * have something random in the field to prevent unfriendly people from - * sending cancels to them. - */ - if (!RandomCancelKey(&MyCancelKey)) - { - ereport(LOG, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("could not generate random cancel key"))); - return false; - } - bn = palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM); if (bn == NULL) { @@ -5900,7 +5763,6 @@ assign_backendlist_entry(RegisteredBgWorker *rw) return false; } - bn->cancel_key = MyCancelKey; bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot(); bn->bkend_type = BACKEND_TYPE_BGWORKER; bn->dead_end = false; @@ -6129,7 +5991,6 @@ save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *w param->UsedShmemSegAddr = UsedShmemSegAddr; param->ShmemLock = ShmemLock; - param->ShmemBackendArray = ShmemBackendArray; #ifndef HAVE_SPINLOCKS param->SpinlockSemaArray = SpinlockSemaArray; @@ -6374,7 +6235,6 @@ restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorke UsedShmemSegAddr = param->UsedShmemSegAddr; ShmemLock = param->ShmemLock; - ShmemBackendArray = param->ShmemBackendArray; #ifndef HAVE_SPINLOCKS SpinlockSemaArray = param->SpinlockSemaArray; @@ -6426,43 +6286,6 @@ restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorke ReserveExternalFD(); #endif } - - -Size -ShmemBackendArraySize(void) -{ - return mul_size(MaxLivePostmasterChildren(), sizeof(Backend)); -} - -void -ShmemBackendArrayAllocation(void) -{ - Size size = ShmemBackendArraySize(); - - ShmemBackendArray = (Backend *) ShmemAlloc(size); - /* Mark all slots as empty */ - memset(ShmemBackendArray, 0, size); -} - -static void -ShmemBackendArrayAdd(Backend *bn) -{ - /* The array slot corresponding to my PMChildSlot should be free */ - int i = bn->child_slot - 1; - - Assert(ShmemBackendArray[i].pid == 0); - ShmemBackendArray[i] = *bn; -} - -static void -ShmemBackendArrayRemove(Backend *bn) -{ - int i = bn->child_slot - 1; - - Assert(ShmemBackendArray[i].pid == bn->pid); - /* Mark the slot as empty */ - ShmemBackendArray[i].pid = 0; -} #endif /* EXEC_BACKEND */ diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 7e7941d6259..c2267b7b080 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -155,9 +155,6 @@ CalculateShmemSize(int *num_semaphores) size = add_size(size, WaitEventExtensionShmemSize()); size = add_size(size, InjectionPointShmemSize()); size = add_size(size, SlotSyncShmemSize()); -#ifdef EXEC_BACKEND - size = add_size(size, ShmemBackendArraySize()); -#endif /* include additional requested shmem from preload libraries */ size = add_size(size, total_addin_request); @@ -247,14 +244,6 @@ CreateSharedMemoryAndSemaphores(void) /* Initialize subsystems */ CreateOrAttachShmemStructs(); -#ifdef EXEC_BACKEND - - /* - * Alloc the win32 shared backend array - */ - ShmemBackendArrayAllocation(); -#endif - /* Initialize dynamic shared memory facilities. */ dsm_postmaster_startup(shim); diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index 27844b46a2b..9516b869cb2 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -22,6 +22,7 @@ #endif #include "miscadmin.h" +#include "port/atomics.h" #include "postmaster/postmaster.h" #include "replication/walsender.h" #include "storage/pmsignal.h" @@ -37,9 +38,8 @@ * if the same reason is signaled more than once simultaneously, the * postmaster will observe it only once.) * - * The flags are actually declared as "volatile sig_atomic_t" for maximum - * portability. This should ensure that loads and stores of the flag - * values are atomic, allowing us to dispense with any explicit locking. + * The flag fields use atomics, allowing us to dispense with any explicit + * locking. * * In addition to the per-reason flags, we store a set of per-child-process * flags that are currently used only for detecting whether a backend has @@ -67,20 +67,29 @@ #define PM_CHILD_ACTIVE 2 #define PM_CHILD_WALSENDER 3 +typedef struct ChildSlotData +{ + pg_atomic_uint32 state; + + int pid; + int32 cancel_key; +} ChildSlotData; + /* "typedef struct PMSignalData PMSignalData" appears in pmsignal.h */ struct PMSignalData { /* per-reason flags for signaling the postmaster */ - sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]; + volatile sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]; /* global flags for signals from postmaster to children */ QuitSignalReason sigquit_reason; /* why SIGQUIT was sent */ - /* per-child-process flags */ - int num_child_flags; /* # of entries in PMChildFlags[] */ - sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]; + + /* per-child-process slots */ + int num_child_slots; /* # of entries in child_slots[] */ + ChildSlotData child_slots[FLEXIBLE_ARRAY_MEMBER]; }; /* PMSignalState pointer is valid in both postmaster and child processes */ -NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL; +NON_EXEC_STATIC PMSignalData *PMSignalState = NULL; /* * These static variables are valid only in the postmaster. We keep a @@ -130,9 +139,9 @@ PMSignalShmemSize(void) { Size size; - size = offsetof(PMSignalData, PMChildFlags); + size = offsetof(PMSignalData, child_slots); size = add_size(size, mul_size(MaxLivePostmasterChildren(), - sizeof(sig_atomic_t))); + sizeof(ChildSlotData))); return size; } @@ -151,9 +160,9 @@ PMSignalShmemInit(void) if (!found) { /* initialize all flags to zeroes */ - MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize()); + MemSet(PMSignalState, 0, PMSignalShmemSize()); num_child_inuse = MaxLivePostmasterChildren(); - PMSignalState->num_child_flags = num_child_inuse; + PMSignalState->num_child_slots = num_child_inuse; /* * Also allocate postmaster's private PMChildInUse[] array. We @@ -262,14 +271,14 @@ AssignPostmasterChildSlot(void) if (!PMChildInUse[slot]) { PMChildInUse[slot] = true; - PMSignalState->PMChildFlags[slot] = PM_CHILD_ASSIGNED; + pg_atomic_write_u32(&PMSignalState->child_slots[slot].state, PM_CHILD_ASSIGNED); next_child_inuse = slot; return slot + 1; } } /* Out of slots ... should never happen, else postmaster.c messed up */ - elog(FATAL, "no free slots in PMChildFlags array"); + elog(FATAL, "no free slots in postmaster child array"); return 0; /* keep compiler quiet */ } @@ -283,7 +292,7 @@ AssignPostmasterChildSlot(void) bool ReleasePostmasterChildSlot(int slot) { - bool result; + uint32 oldstate; Assert(slot > 0 && slot <= num_child_inuse); slot--; @@ -293,10 +302,9 @@ ReleasePostmasterChildSlot(int slot) * postmaster.c is such that this might get called twice when a child * crashes. So we don't try to Assert anything about the state. */ - result = (PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED); - PMSignalState->PMChildFlags[slot] = PM_CHILD_UNUSED; + oldstate = pg_atomic_exchange_u32(&PMSignalState->child_slots[slot].state, PM_CHILD_UNUSED); PMChildInUse[slot] = false; - return result; + return oldstate == PM_CHILD_ASSIGNED; } /* @@ -309,7 +317,7 @@ IsPostmasterChildWalSender(int slot) Assert(slot > 0 && slot <= num_child_inuse); slot--; - if (PMSignalState->PMChildFlags[slot] == PM_CHILD_WALSENDER) + if (pg_atomic_read_u32(&PMSignalState->child_slots[slot].state) == PM_CHILD_WALSENDER) return true; else return false; @@ -320,14 +328,17 @@ IsPostmasterChildWalSender(int slot) * actively using shared memory. This is called in the child process. */ void -MarkPostmasterChildActive(void) +MarkPostmasterChildActive(int pid, int32 cancelAuthCode) { int slot = MyPMChildSlot; - Assert(slot > 0 && slot <= PMSignalState->num_child_flags); + Assert(slot > 0 && slot <= PMSignalState->num_child_slots); slot--; - Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED); - PMSignalState->PMChildFlags[slot] = PM_CHILD_ACTIVE; + Assert(pg_atomic_read_u32(&PMSignalState->child_slots[slot].state) == PM_CHILD_ASSIGNED); + PMSignalState->child_slots[slot].pid = pid; + PMSignalState->child_slots[slot].cancel_key = cancelAuthCode; + pg_memory_barrier(); + pg_atomic_write_u32(&PMSignalState->child_slots[slot].state, PM_CHILD_ACTIVE); } /* @@ -342,10 +353,10 @@ MarkPostmasterChildWalSender(void) Assert(am_walsender); - Assert(slot > 0 && slot <= PMSignalState->num_child_flags); + Assert(slot > 0 && slot <= PMSignalState->num_child_slots); slot--; - Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ACTIVE); - PMSignalState->PMChildFlags[slot] = PM_CHILD_WALSENDER; + Assert(pg_atomic_read_u32(&PMSignalState->child_slots[slot].state) == PM_CHILD_ACTIVE); + pg_atomic_write_u32(&PMSignalState->child_slots[slot].state, PM_CHILD_WALSENDER); } /* @@ -357,11 +368,17 @@ MarkPostmasterChildInactive(void) { int slot = MyPMChildSlot; - Assert(slot > 0 && slot <= PMSignalState->num_child_flags); + Assert(slot > 0 && slot <= PMSignalState->num_child_slots); slot--; - Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ACTIVE || - PMSignalState->PMChildFlags[slot] == PM_CHILD_WALSENDER); - PMSignalState->PMChildFlags[slot] = PM_CHILD_ASSIGNED; +#ifdef USE_ASSERT_CHECKING + { + uint32 oldstate; + + oldstate = pg_atomic_read_u32(&PMSignalState->child_slots[slot].state); + Assert(oldstate == PM_CHILD_ACTIVE || oldstate == PM_CHILD_WALSENDER); + } +#endif + pg_atomic_write_u32(&PMSignalState->child_slots[slot].state, PM_CHILD_ASSIGNED); } @@ -460,3 +477,50 @@ PostmasterDeathSignalInit(void) postmaster_possibly_dead = true; #endif /* USE_POSTMASTER_DEATH_SIGNAL */ } + +void +SendCancelRequest(int backendPID, int32 cancelAuthCode) +{ + /* + * See if we have a matching backend. In the EXEC_BACKEND case, we can no + * longer access the postmaster's own backend list, and must rely on the + * duplicate array in shared memory. XXX + */ + for (int i = MaxLivePostmasterChildren() - 1; i >= 0; i--) + { + ChildSlotData *slot = &PMSignalState->child_slots[i]; + uint32 state = pg_atomic_read_u32(&slot->state); + + if (state != PM_CHILD_ACTIVE) + continue; + + pg_read_barrier(); + if (slot->pid == backendPID) + { + if (slot->cancel_key == cancelAuthCode) + { + /* Found a match; signal that backend to cancel current op */ + ereport(DEBUG2, + (errmsg_internal("processing cancel request: sending SIGINT to process %d", + backendPID))); + + /* + * FIXME: we used to use signal_child. I believe kill() is + * maybe even more correct, but verify that. + */ + kill(backendPID, SIGINT); + } + else + /* Right PID, wrong key: no way, Jose */ + ereport(LOG, + (errmsg("wrong key in cancel request for process %d", + backendPID))); + return; + } + } + + /* No matching backend */ + ereport(LOG, + (errmsg("PID %d in cancel request did not match any process", + backendPID))); +} diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 6e334971dc9..5984fe7d44c 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -310,6 +310,20 @@ InitProcess(void) if (MyProc != NULL) elog(ERROR, "you already exist"); + /* + * Generate a random cancel key. + * + * We probably don't need cancel keys for non-backend processes, but we'd + * better have something random in the field to prevent unfriendly people + * from sending cancels to them. + */ + if (!pg_strong_random(&MyCancelKey, sizeof(int32))) + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not generate random cancel key"))); + } + /* Decide which list should supply our PGPROC. */ if (IsAnyAutoVacuumProcess()) procgloballist = &ProcGlobal->autovacFreeProcs; @@ -373,7 +387,7 @@ InitProcess(void) */ if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess() && !IsLogicalSlotSyncWorker()) - MarkPostmasterChildActive(); + MarkPostmasterChildActive(MyProcPid, MyCancelKey); /* * Initialize all fields of MyProc, except for those previously diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 03f78b5b25f..7cfd07a2bda 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -61,9 +61,6 @@ extern bool PostmasterMarkPIDForWorkerNotify(int); #ifdef EXEC_BACKEND extern pid_t postmaster_forkexec(int argc, char *argv[]); extern void SubPostmasterMain(int argc, char *argv[]) pg_attribute_noreturn(); - -extern Size ShmemBackendArraySize(void); -extern void ShmemBackendArrayAllocation(void); #endif /* diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h index 029b7201093..8dff47e86e4 100644 --- a/src/include/storage/pmsignal.h +++ b/src/include/storage/pmsignal.h @@ -69,11 +69,12 @@ extern QuitSignalReason GetQuitSignalReason(void); extern int AssignPostmasterChildSlot(void); extern bool ReleasePostmasterChildSlot(int slot); extern bool IsPostmasterChildWalSender(int slot); -extern void MarkPostmasterChildActive(void); +extern void MarkPostmasterChildActive(int pid, int32 cancelAuthCode); extern void MarkPostmasterChildInactive(void); extern void MarkPostmasterChildWalSender(void); extern bool PostmasterIsAliveInternal(void); extern void PostmasterDeathSignalInit(void); +extern void SendCancelRequest(int backendPID, int32 cancelAuthCode); /* diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index fc8b15d0cf2..ac0085a226f 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -375,6 +375,7 @@ CatalogId CatalogIdMapEntry CatalogIndexState ChangeVarNodes_context +ChildSlotData ReplaceVarnoContext CheckPoint CheckPointStmt -- 2.39.2