diff options
Diffstat (limited to 'src/backend/storage')
-rw-r--r-- | src/backend/storage/ipc/pmsignal.c | 89 | ||||
-rw-r--r-- | src/backend/storage/lmgr/proc.c | 12 |
2 files changed, 30 insertions, 71 deletions
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index c801e9bec51..c764d6af4fc 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -47,11 +47,11 @@ * exited without performing proper shutdown. The per-child-process flags * have three possible states: UNUSED, ASSIGNED, ACTIVE. An UNUSED slot is * available for assignment. An ASSIGNED slot is associated with a postmaster - * child process, but either the process has not touched shared memory yet, - * or it has successfully cleaned up after itself. A ACTIVE slot means the - * process is actively using shared memory. The slots are assigned to - * child processes at random, and postmaster.c is responsible for tracking - * which one goes with which PID. + * child process, but either the process has not touched shared memory yet, or + * it has successfully cleaned up after itself. An ACTIVE slot means the + * process is actively using shared memory. The slots are assigned to child + * processes by postmaster, and pmchild.c is responsible for tracking which + * one goes with which PID. * * Actually there is a fourth state, WALSENDER. This is just like ACTIVE, * but carries the extra information that the child is a WAL sender. @@ -84,13 +84,11 @@ struct PMSignalData NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL; /* - * These static variables are valid only in the postmaster. We keep a - * duplicative private array so that we can trust its state even if some - * failing child has clobbered the PMSignalData struct in shared memory. + * Local copy of PMSignalState->num_child_flags, only valid in the + * postmaster. Postmaster keeps a local copy so that it doesn't need to + * trust the value in shared memory. */ -static int num_child_inuse; /* # of entries in PMChildInUse[] */ -static int next_child_inuse; /* next slot to try to assign */ -static bool *PMChildInUse; /* true if i'th flag slot is assigned */ +static int num_child_flags; /* * Signal handler to be notified if postmaster dies. @@ -155,25 +153,8 @@ PMSignalShmemInit(void) { /* initialize all flags to zeroes */ MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize()); - num_child_inuse = MaxLivePostmasterChildren(); - PMSignalState->num_child_flags = num_child_inuse; - - /* - * Also allocate postmaster's private PMChildInUse[] array. We - * might've already done that in a previous shared-memory creation - * cycle, in which case free the old array to avoid a leak. (Do it - * like this to support the possibility that MaxLivePostmasterChildren - * changed.) In a standalone backend, we do not need this. - */ - if (PostmasterContext != NULL) - { - if (PMChildInUse) - pfree(PMChildInUse); - PMChildInUse = (bool *) - MemoryContextAllocZero(PostmasterContext, - num_child_inuse * sizeof(bool)); - } - next_child_inuse = 0; + num_child_flags = MaxLivePostmasterChildren(); + PMSignalState->num_child_flags = num_child_flags; } } @@ -239,56 +220,37 @@ GetQuitSignalReason(void) /* - * AssignPostmasterChildSlot - select an unused slot for a new postmaster - * child process, and set its state to ASSIGNED. Returns a slot number - * (one to N). + * MarkPostmasterChildSlotAssigned - mark the given slot as ASSIGNED for a + * new postmaster child process. * * Only the postmaster is allowed to execute this routine, so we need no * special locking. */ -int -AssignPostmasterChildSlot(void) +void +MarkPostmasterChildSlotAssigned(int slot) { - int slot = next_child_inuse; - int n; + Assert(slot > 0 && slot <= num_child_flags); + slot--; - /* - * Scan for a free slot. Notice that we trust nothing about the contents - * of PMSignalState, but use only postmaster-local data for this decision. - * We track the last slot assigned so as not to waste time repeatedly - * rescanning low-numbered slots. - */ - for (n = num_child_inuse; n > 0; n--) - { - if (--slot < 0) - slot = num_child_inuse - 1; - if (!PMChildInUse[slot]) - { - PMChildInUse[slot] = true; - PMSignalState->PMChildFlags[slot] = PM_CHILD_ASSIGNED; - next_child_inuse = slot; - return slot + 1; - } - } + if (PMSignalState->PMChildFlags[slot] != PM_CHILD_UNUSED) + elog(FATAL, "postmaster child slot is already in use"); - /* Out of slots ... should never happen, else postmaster.c messed up */ - elog(FATAL, "no free slots in PMChildFlags array"); - return 0; /* keep compiler quiet */ + PMSignalState->PMChildFlags[slot] = PM_CHILD_ASSIGNED; } /* - * ReleasePostmasterChildSlot - release a slot after death of a postmaster - * child process. This must be called in the postmaster process. + * MarkPostmasterChildSlotUnassigned - release a slot after death of a + * postmaster child process. This must be called in the postmaster process. * * Returns true if the slot had been in ASSIGNED state (the expected case), * false otherwise (implying that the child failed to clean itself up). */ bool -ReleasePostmasterChildSlot(int slot) +MarkPostmasterChildSlotUnassigned(int slot) { bool result; - Assert(slot > 0 && slot <= num_child_inuse); + Assert(slot > 0 && slot <= num_child_flags); slot--; /* @@ -298,7 +260,6 @@ ReleasePostmasterChildSlot(int slot) */ result = (PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED); PMSignalState->PMChildFlags[slot] = PM_CHILD_UNUSED; - PMChildInUse[slot] = false; return result; } @@ -309,7 +270,7 @@ ReleasePostmasterChildSlot(int slot) bool IsPostmasterChildWalSender(int slot) { - Assert(slot > 0 && slot <= num_child_inuse); + Assert(slot > 0 && slot <= num_child_flags); slot--; if (PMSignalState->PMChildFlags[slot] == PM_CHILD_WALSENDER) diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 772e6fdbf28..720ef99ee83 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -353,14 +353,9 @@ InitProcess(void) /* * Before we start accessing the shared memory in a serious way, mark * ourselves as an active postmaster child; this is so that the postmaster - * can detect it if we exit without cleaning up. (XXX autovac launcher - * currently doesn't participate in this; it probably should.) - * - * Slot sync worker also does not participate in it, see comments atop - * 'struct bkend' in postmaster.c. + * can detect it if we exit without cleaning up. */ - if (IsUnderPostmaster && !AmAutoVacuumLauncherProcess() && - !AmLogicalSlotSyncWorkerProcess()) + if (IsUnderPostmaster) RegisterPostmasterChildActive(); /* Decide which list should supply our PGPROC. */ @@ -578,6 +573,9 @@ InitAuxiliaryProcess(void) if (MyProc != NULL) elog(ERROR, "you already exist"); + if (IsUnderPostmaster) + RegisterPostmasterChildActive(); + /* * We use the ProcStructLock to protect assignment and releasing of * AuxiliaryProcs entries. |