#include "storage/backendid.h"
Go to the source code of this file.
Enumerations | |
enum | ProcSignalReason { PROCSIG_CATCHUP_INTERRUPT, PROCSIG_NOTIFY_INTERRUPT, PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, NUM_PROCSIGNALS } |
Functions | |
Size | ProcSignalShmemSize (void) |
void | ProcSignalShmemInit (void) |
void | ProcSignalInit (int pss_idx) |
int | SendProcSignal (pid_t pid, ProcSignalReason reason, BackendId backendId) |
void | procsignal_sigusr1_handler (SIGNAL_ARGS) |
enum ProcSignalReason |
Definition at line 30 of file procsignal.h.
{ PROCSIG_CATCHUP_INTERRUPT, /* sinval catchup interrupt */ PROCSIG_NOTIFY_INTERRUPT, /* listen/notify interrupt */ /* Recovery conflict reasons */ PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, NUM_PROCSIGNALS /* Must be last! */ } ProcSignalReason;
void procsignal_sigusr1_handler | ( | SIGNAL_ARGS | ) |
Definition at line 251 of file procsignal.c.
References CheckProcSignal(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), latch_sigusr1_handler(), PROCSIG_CATCHUP_INTERRUPT, PROCSIG_NOTIFY_INTERRUPT, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, and RecoveryConflictInterrupt().
Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), and PostgresMain().
{ int save_errno = errno; if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT)) HandleCatchupInterrupt(); if (CheckProcSignal(PROCSIG_NOTIFY_INTERRUPT)) HandleNotifyInterrupt(); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_DATABASE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_DATABASE); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_TABLESPACE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_TABLESPACE); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_LOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_LOCK); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK); if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN); latch_sigusr1_handler(); errno = save_errno; }
void ProcSignalInit | ( | int | pss_idx | ) |
Definition at line 102 of file procsignal.c.
References Assert, CleanupProcSignalState(), elog, Int32GetDatum, LOG, MemSet, MyProcPid, NUM_PROCSIGNALS, NumProcSignalSlots, on_shmem_exit(), ProcSignalSlot::pss_pid, and ProcSignalSlot::pss_signalFlags.
Referenced by AuxiliaryProcessMain(), and InitPostgres().
{ volatile ProcSignalSlot *slot; Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots); slot = &ProcSignalSlots[pss_idx - 1]; /* sanity check */ if (slot->pss_pid != 0) elog(LOG, "process %d taking over ProcSignal slot %d, but it's not empty", MyProcPid, pss_idx); /* Clear out any leftover signal reasons */ MemSet(slot->pss_signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t)); /* Mark slot with my PID */ slot->pss_pid = MyProcPid; /* Remember slot location for CheckProcSignal */ MyProcSignalSlot = slot; /* Set up to release the slot on process exit */ on_shmem_exit(CleanupProcSignalState, Int32GetDatum(pss_idx)); }
void ProcSignalShmemInit | ( | void | ) |
Definition at line 81 of file procsignal.c.
References MemSet, ProcSignalShmemSize(), and ShmemInitStruct().
Referenced by CreateSharedMemoryAndSemaphores().
{ Size size = ProcSignalShmemSize(); bool found; ProcSignalSlots = (ProcSignalSlot *) ShmemInitStruct("ProcSignalSlots", size, &found); /* If we're first, set everything to zeroes */ if (!found) MemSet(ProcSignalSlots, 0, size); }
Size ProcSignalShmemSize | ( | void | ) |
Definition at line 71 of file procsignal.c.
References NumProcSignalSlots.
Referenced by CreateSharedMemoryAndSemaphores(), and ProcSignalShmemInit().
{ return NumProcSignalSlots * sizeof(ProcSignalSlot); }
int SendProcSignal | ( | pid_t | pid, | |
ProcSignalReason | reason, | |||
BackendId | backendId | |||
) |
Definition at line 170 of file procsignal.c.
References i, InvalidBackendId, NumProcSignalSlots, ProcSignalSlot::pss_pid, ProcSignalSlot::pss_signalFlags, and SIGUSR1.
Referenced by CancelDBBackends(), CancelVirtualTransaction(), SICleanupQueue(), and SignalBackends().
{ volatile ProcSignalSlot *slot; if (backendId != InvalidBackendId) { slot = &ProcSignalSlots[backendId - 1]; /* * Note: Since there's no locking, it's possible that the target * process detaches from shared memory and exits right after this * test, before we set the flag and send signal. And the signal slot * might even be recycled by a new process, so it's remotely possible * that we set a flag for a wrong process. That's OK, all the signals * are such that no harm is done if they're mistakenly fired. */ if (slot->pss_pid == pid) { /* Atomically set the proper flag */ slot->pss_signalFlags[reason] = true; /* Send signal */ return kill(pid, SIGUSR1); } } else { /* * BackendId not provided, so search the array using pid. We search * the array back to front so as to reduce search overhead. Passing * InvalidBackendId means that the target is most likely an auxiliary * process, which will have a slot near the end of the array. */ int i; for (i = NumProcSignalSlots - 1; i >= 0; i--) { slot = &ProcSignalSlots[i]; if (slot->pss_pid == pid) { /* the above note about race conditions applies here too */ /* Atomically set the proper flag */ slot->pss_signalFlags[reason] = true; /* Send signal */ return kill(pid, SIGUSR1); } } } errno = ESRCH; return -1; }