PostgreSQL Source Code  git master
procsignal.c File Reference
#include "postgres.h"
#include <signal.h>
#include <unistd.h>
#include "access/parallel.h"
#include "commands/async.h"
#include "miscadmin.h"
#include "replication/walsender.h"
#include "storage/latch.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/shmem.h"
#include "storage/sinval.h"
#include "tcop/tcopprot.h"
Include dependency graph for procsignal.c:

Go to the source code of this file.

Data Structures

struct  ProcSignalSlot
 

Macros

#define NumProcSignalSlots   (MaxBackends + NUM_AUXPROCTYPES)
 

Functions

static bool CheckProcSignal (ProcSignalReason reason)
 
static void CleanupProcSignalState (int status, Datum arg)
 
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)
 

Variables

static ProcSignalSlotProcSignalSlots = NULL
 
static volatile ProcSignalSlotMyProcSignalSlot = NULL
 

Macro Definition Documentation

◆ NumProcSignalSlots

#define NumProcSignalSlots   (MaxBackends + NUM_AUXPROCTYPES)

Definition at line 61 of file procsignal.c.

Referenced by ProcSignalInit(), ProcSignalShmemSize(), and SendProcSignal().

Function Documentation

◆ CheckProcSignal()

static bool CheckProcSignal ( ProcSignalReason  reason)
static

Definition at line 240 of file procsignal.c.

References MyProcSignalSlot, and ProcSignalSlot::pss_signalFlags.

Referenced by procsignal_sigusr1_handler().

241 {
242  volatile ProcSignalSlot *slot = MyProcSignalSlot;
243 
244  if (slot != NULL)
245  {
246  /* Careful here --- don't clear flag if we haven't seen it set */
247  if (slot->pss_signalFlags[reason])
248  {
249  slot->pss_signalFlags[reason] = false;
250  return true;
251  }
252  }
253 
254  return false;
255 }
sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]
Definition: procsignal.c:53
static volatile ProcSignalSlot * MyProcSignalSlot
Definition: procsignal.c:64

◆ CleanupProcSignalState()

static void CleanupProcSignalState ( int  status,
Datum  arg 
)
static

Definition at line 138 of file procsignal.c.

References Assert, DatumGetInt32, elog, LOG, MyProcPid, and ProcSignalSlot::pss_pid.

Referenced by ProcSignalInit().

139 {
140  int pss_idx = DatumGetInt32(arg);
141  volatile ProcSignalSlot *slot;
142 
143  slot = &ProcSignalSlots[pss_idx - 1];
144  Assert(slot == MyProcSignalSlot);
145 
146  /*
147  * Clear MyProcSignalSlot, so that a SIGUSR1 received after this point
148  * won't try to access it after it's no longer ours (and perhaps even
149  * after we've unmapped the shared memory segment).
150  */
151  MyProcSignalSlot = NULL;
152 
153  /* sanity check */
154  if (slot->pss_pid != MyProcPid)
155  {
156  /*
157  * don't ERROR here. We're exiting anyway, and don't want to get into
158  * infinite loop trying to exit
159  */
160  elog(LOG, "process %d releasing ProcSignal slot %d, but it contains %d",
161  MyProcPid, pss_idx, (int) slot->pss_pid);
162  return; /* XXX better to zero the slot anyway? */
163  }
164 
165  slot->pss_pid = 0;
166 }
static ProcSignalSlot * ProcSignalSlots
Definition: procsignal.c:63
int MyProcPid
Definition: globals.c:39
#define DatumGetInt32(X)
Definition: postgres.h:478
#define LOG
Definition: elog.h:26
#define Assert(condition)
Definition: c.h:670
void * arg
static volatile ProcSignalSlot * MyProcSignalSlot
Definition: procsignal.c:64
#define elog
Definition: elog.h:219

◆ procsignal_sigusr1_handler()

void procsignal_sigusr1_handler ( SIGNAL_ARGS  )

Definition at line 261 of file procsignal.c.

References CheckProcSignal(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), HandleParallelMessageInterrupt(), HandleWalSndInitStopping(), latch_sigusr1_handler(), MyLatch, PROCSIG_CATCHUP_INTERRUPT, PROCSIG_NOTIFY_INTERRUPT, PROCSIG_PARALLEL_MESSAGE, 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, PROCSIG_WALSND_INIT_STOPPING, RecoveryConflictInterrupt(), and SetLatch().

Referenced by autoprewarm_main(), AutoVacLauncherMain(), AutoVacWorkerMain(), PostgresMain(), StartBackgroundWorker(), and WalSndSignals().

262 {
263  int save_errno = errno;
264 
267 
270 
273 
276 
279 
282 
285 
288 
291 
294 
295  SetLatch(MyLatch);
296 
298 
299  errno = save_errno;
300 }
void RecoveryConflictInterrupt(ProcSignalReason reason)
Definition: postgres.c:2740
void HandleWalSndInitStopping(void)
Definition: walsender.c:2902
static bool CheckProcSignal(ProcSignalReason reason)
Definition: procsignal.c:240
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
void HandleNotifyInterrupt(void)
Definition: async.c:1707
struct Latch * MyLatch
Definition: globals.c:52
void HandleParallelMessageInterrupt(void)
Definition: parallel.c:715
void latch_sigusr1_handler(void)
Definition: latch.c:1473
void HandleCatchupInterrupt(void)
Definition: sinval.c:157

◆ ProcSignalInit()

void ProcSignalInit ( int  pss_idx)

Definition at line 105 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().

106 {
107  volatile ProcSignalSlot *slot;
108 
109  Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots);
110 
111  slot = &ProcSignalSlots[pss_idx - 1];
112 
113  /* sanity check */
114  if (slot->pss_pid != 0)
115  elog(LOG, "process %d taking over ProcSignal slot %d, but it's not empty",
116  MyProcPid, pss_idx);
117 
118  /* Clear out any leftover signal reasons */
119  MemSet(slot->pss_signalFlags, 0, NUM_PROCSIGNALS * sizeof(sig_atomic_t));
120 
121  /* Mark slot with my PID */
122  slot->pss_pid = MyProcPid;
123 
124  /* Remember slot location for CheckProcSignal */
125  MyProcSignalSlot = slot;
126 
127  /* Set up to release the slot on process exit */
129 }
static ProcSignalSlot * ProcSignalSlots
Definition: procsignal.c:63
int MyProcPid
Definition: globals.c:39
#define MemSet(start, val, len)
Definition: c.h:853
#define LOG
Definition: elog.h:26
static void CleanupProcSignalState(int status, Datum arg)
Definition: procsignal.c:138
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
#define Assert(condition)
Definition: c.h:670
#define Int32GetDatum(X)
Definition: postgres.h:485
sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]
Definition: procsignal.c:53
static volatile ProcSignalSlot * MyProcSignalSlot
Definition: procsignal.c:64
#define NumProcSignalSlots
Definition: procsignal.c:61
#define elog
Definition: elog.h:219

◆ ProcSignalShmemInit()

void ProcSignalShmemInit ( void  )

Definition at line 84 of file procsignal.c.

References MemSet, ProcSignalShmemSize(), and ShmemInitStruct().

Referenced by CreateSharedMemoryAndSemaphores().

85 {
86  Size size = ProcSignalShmemSize();
87  bool found;
88 
90  ShmemInitStruct("ProcSignalSlots", size, &found);
91 
92  /* If we're first, set everything to zeroes */
93  if (!found)
94  MemSet(ProcSignalSlots, 0, size);
95 }
static ProcSignalSlot * ProcSignalSlots
Definition: procsignal.c:63
#define MemSet(start, val, len)
Definition: c.h:853
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:372
Size ProcSignalShmemSize(void)
Definition: procsignal.c:74
size_t Size
Definition: c.h:404

◆ ProcSignalShmemSize()

Size ProcSignalShmemSize ( void  )

Definition at line 74 of file procsignal.c.

References NumProcSignalSlots.

Referenced by CreateSharedMemoryAndSemaphores(), and ProcSignalShmemInit().

75 {
76  return NumProcSignalSlots * sizeof(ProcSignalSlot);
77 }
#define NumProcSignalSlots
Definition: procsignal.c:61

◆ SendProcSignal()

int SendProcSignal ( pid_t  pid,
ProcSignalReason  reason,
BackendId  backendId 
)

Definition at line 180 of file procsignal.c.

References i, InvalidBackendId, kill, NumProcSignalSlots, ProcSignalSlot::pss_pid, ProcSignalSlot::pss_signalFlags, and SIGUSR1.

Referenced by CancelDBBackends(), CancelVirtualTransaction(), mq_putmessage(), SICleanupQueue(), SignalBackends(), and WalSndInitStopping().

181 {
182  volatile ProcSignalSlot *slot;
183 
184  if (backendId != InvalidBackendId)
185  {
186  slot = &ProcSignalSlots[backendId - 1];
187 
188  /*
189  * Note: Since there's no locking, it's possible that the target
190  * process detaches from shared memory and exits right after this
191  * test, before we set the flag and send signal. And the signal slot
192  * might even be recycled by a new process, so it's remotely possible
193  * that we set a flag for a wrong process. That's OK, all the signals
194  * are such that no harm is done if they're mistakenly fired.
195  */
196  if (slot->pss_pid == pid)
197  {
198  /* Atomically set the proper flag */
199  slot->pss_signalFlags[reason] = true;
200  /* Send signal */
201  return kill(pid, SIGUSR1);
202  }
203  }
204  else
205  {
206  /*
207  * BackendId not provided, so search the array using pid. We search
208  * the array back to front so as to reduce search overhead. Passing
209  * InvalidBackendId means that the target is most likely an auxiliary
210  * process, which will have a slot near the end of the array.
211  */
212  int i;
213 
214  for (i = NumProcSignalSlots - 1; i >= 0; i--)
215  {
216  slot = &ProcSignalSlots[i];
217 
218  if (slot->pss_pid == pid)
219  {
220  /* the above note about race conditions applies here too */
221 
222  /* Atomically set the proper flag */
223  slot->pss_signalFlags[reason] = true;
224  /* Send signal */
225  return kill(pid, SIGUSR1);
226  }
227  }
228  }
229 
230  errno = ESRCH;
231  return -1;
232 }
static ProcSignalSlot * ProcSignalSlots
Definition: procsignal.c:63
#define SIGUSR1
Definition: win32_port.h:177
#define kill(pid, sig)
Definition: win32_port.h:437
#define InvalidBackendId
Definition: backendid.h:23
int i
sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]
Definition: procsignal.c:53
#define NumProcSignalSlots
Definition: procsignal.c:61

Variable Documentation

◆ MyProcSignalSlot

volatile ProcSignalSlot* MyProcSignalSlot = NULL
static

Definition at line 64 of file procsignal.c.

Referenced by CheckProcSignal().

◆ ProcSignalSlots

ProcSignalSlot* ProcSignalSlots = NULL
static

Definition at line 63 of file procsignal.c.