PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "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

#define NumProcSignalSlots   (MaxBackends + NUM_AUXPROCTYPES)

Definition at line 60 of file procsignal.c.

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

Function Documentation

static bool CheckProcSignal ( ProcSignalReason  reason)
static

Definition at line 239 of file procsignal.c.

References MyProcSignalSlot, NULL, and ProcSignalSlot::pss_signalFlags.

Referenced by procsignal_sigusr1_handler().

240 {
241  volatile ProcSignalSlot *slot = MyProcSignalSlot;
242 
243  if (slot != NULL)
244  {
245  /* Careful here --- don't clear flag if we haven't seen it set */
246  if (slot->pss_signalFlags[reason])
247  {
248  slot->pss_signalFlags[reason] = false;
249  return true;
250  }
251  }
252 
253  return false;
254 }
#define NULL
Definition: c.h:229
sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]
Definition: procsignal.c:52
static volatile ProcSignalSlot * MyProcSignalSlot
Definition: procsignal.c:63
static void CleanupProcSignalState ( int  status,
Datum  arg 
)
static

Definition at line 137 of file procsignal.c.

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

Referenced by ProcSignalInit().

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

Definition at line 260 of file procsignal.c.

References CheckProcSignal(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), HandleParallelMessageInterrupt(), 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, RecoveryConflictInterrupt(), and SetLatch().

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

261 {
262  int save_errno = errno;
263 
266 
269 
272 
275 
278 
281 
284 
287 
290 
291  SetLatch(MyLatch);
292 
294 
295  errno = save_errno;
296 }
void RecoveryConflictInterrupt(ProcSignalReason reason)
Definition: postgres.c:2699
static bool CheckProcSignal(ProcSignalReason reason)
Definition: procsignal.c:239
void SetLatch(volatile Latch *latch)
Definition: latch.c:379
void HandleNotifyInterrupt(void)
Definition: async.c:1702
struct Latch * MyLatch
Definition: globals.c:51
void HandleParallelMessageInterrupt(void)
Definition: parallel.c:694
void latch_sigusr1_handler(void)
Definition: latch.c:1572
void HandleCatchupInterrupt(void)
Definition: sinval.c:157
void ProcSignalInit ( int  pss_idx)

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

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

Definition at line 83 of file procsignal.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

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

Definition at line 73 of file procsignal.c.

References NumProcSignalSlots.

Referenced by CreateSharedMemoryAndSemaphores(), and ProcSignalShmemInit().

74 {
75  return NumProcSignalSlots * sizeof(ProcSignalSlot);
76 }
#define NumProcSignalSlots
Definition: procsignal.c:60
int SendProcSignal ( pid_t  pid,
ProcSignalReason  reason,
BackendId  backendId 
)

Definition at line 179 of file procsignal.c.

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

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

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

Variable Documentation

volatile ProcSignalSlot* MyProcSignalSlot = NULL
static

Definition at line 63 of file procsignal.c.

Referenced by CheckProcSignal().

ProcSignalSlot* ProcSignalSlots = NULL
static

Definition at line 62 of file procsignal.c.