aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/storage/ipc/procsignal.c9
-rw-r--r--src/backend/storage/lmgr/proc.c42
2 files changed, 33 insertions, 18 deletions
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 6ebabce72f7..6526b2688a8 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -149,6 +149,13 @@ CleanupProcSignalState(int status, Datum arg)
slot = &ProcSignalSlots[pss_idx - 1];
Assert(slot == MyProcSignalSlot);
+ /*
+ * Clear MyProcSignalSlot, so that a SIGUSR1 received after this point
+ * won't try to access it after it's no longer ours (and perhaps even
+ * after we've unmapped the shared memory segment).
+ */
+ MyProcSignalSlot = NULL;
+
/* sanity check */
if (slot->pss_pid != MyProcPid)
{
@@ -285,7 +292,7 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
- if (set_latch_on_sigusr1)
+ if (set_latch_on_sigusr1 && MyProc != NULL)
SetLatch(&MyProc->procLatch);
latch_sigusr1_handler();
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 1a683b83361..9d32f9405d5 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -773,6 +773,7 @@ ProcKill(int code, Datum arg)
{
/* use volatile pointer to prevent code rearrangement */
volatile PROC_HDR *procglobal = ProcGlobal;
+ PGPROC *proc;
Assert(MyProc != NULL);
@@ -797,31 +798,34 @@ ProcKill(int code, Datum arg)
*/
LWLockReleaseAll();
- /* Release ownership of the process's latch, too */
- DisownLatch(&MyProc->procLatch);
+ /*
+ * Clear MyProc first; then disown the process latch. This is so that
+ * signal handlers won't try to clear the process latch after it's no
+ * longer ours.
+ */
+ proc = MyProc;
+ MyProc = NULL;
+ DisownLatch(&proc->procLatch);
SpinLockAcquire(ProcStructLock);
/* Return PGPROC structure (and semaphore) to appropriate freelist */
if (IsAnyAutoVacuumProcess())
{
- MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
- procglobal->autovacFreeProcs = MyProc;
+ proc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
+ procglobal->autovacFreeProcs = proc;
}
else if (IsBackgroundWorker)
{
- MyProc->links.next = (SHM_QUEUE *) procglobal->bgworkerFreeProcs;
- procglobal->bgworkerFreeProcs = MyProc;
+ proc->links.next = (SHM_QUEUE *) procglobal->bgworkerFreeProcs;
+ procglobal->bgworkerFreeProcs = proc;
}
else
{
- MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
- procglobal->freeProcs = MyProc;
+ proc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
+ procglobal->freeProcs = proc;
}
- /* PGPROC struct isn't mine anymore */
- MyProc = NULL;
-
/* Update shared estimate of spins_per_delay */
procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay);
@@ -850,6 +854,7 @@ AuxiliaryProcKill(int code, Datum arg)
{
int proctype = DatumGetInt32(arg);
PGPROC *auxproc PG_USED_FOR_ASSERTS_ONLY;
+ PGPROC *proc;
Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
@@ -860,16 +865,19 @@ AuxiliaryProcKill(int code, Datum arg)
/* Release any LW locks I am holding (see notes above) */
LWLockReleaseAll();
- /* Release ownership of the process's latch, too */
- DisownLatch(&MyProc->procLatch);
+ /*
+ * Clear MyProc first; then disown the process latch. This is so that
+ * signal handlers won't try to clear the process latch after it's no
+ * longer ours.
+ */
+ proc = MyProc;
+ MyProc = NULL;
+ DisownLatch(&proc->procLatch);
SpinLockAcquire(ProcStructLock);
/* Mark auxiliary proc no longer in use */
- MyProc->pid = 0;
-
- /* PGPROC struct isn't mine anymore */
- MyProc = NULL;
+ proc->pid = 0;
/* Update shared estimate of spins_per_delay */
ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);