PostgreSQL Source Code  git master
pmsignal.c File Reference
#include "postgres.h"
#include <signal.h>
#include <unistd.h>
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "replication/walsender.h"
#include "storage/pmsignal.h"
#include "storage/shmem.h"
#include "utils/memutils.h"
Include dependency graph for pmsignal.c:

Go to the source code of this file.

Data Structures

struct  PMSignalData
 

Macros

#define PM_CHILD_UNUSED   0 /* these values must fit in sig_atomic_t */
 
#define PM_CHILD_ASSIGNED   1
 
#define PM_CHILD_ACTIVE   2
 
#define PM_CHILD_WALSENDER   3
 

Functions

Size PMSignalShmemSize (void)
 
void PMSignalShmemInit (void)
 
void SendPostmasterSignal (PMSignalReason reason)
 
bool CheckPostmasterSignal (PMSignalReason reason)
 
void SetQuitSignalReason (QuitSignalReason reason)
 
QuitSignalReason GetQuitSignalReason (void)
 
int AssignPostmasterChildSlot (void)
 
bool ReleasePostmasterChildSlot (int slot)
 
bool IsPostmasterChildWalSender (int slot)
 
void MarkPostmasterChildActive (void)
 
void MarkPostmasterChildWalSender (void)
 
void MarkPostmasterChildInactive (void)
 
bool PostmasterIsAliveInternal (void)
 
void PostmasterDeathSignalInit (void)
 

Variables

NON_EXEC_STATIC volatile PMSignalDataPMSignalState = NULL
 
static int num_child_inuse
 
static int next_child_inuse
 
static boolPMChildInUse
 

Macro Definition Documentation

◆ PM_CHILD_ACTIVE

#define PM_CHILD_ACTIVE   2

Definition at line 67 of file pmsignal.c.

◆ PM_CHILD_ASSIGNED

#define PM_CHILD_ASSIGNED   1

Definition at line 66 of file pmsignal.c.

◆ PM_CHILD_UNUSED

#define PM_CHILD_UNUSED   0 /* these values must fit in sig_atomic_t */

Definition at line 65 of file pmsignal.c.

◆ PM_CHILD_WALSENDER

#define PM_CHILD_WALSENDER   3

Definition at line 68 of file pmsignal.c.

Function Documentation

◆ AssignPostmasterChildSlot()

int AssignPostmasterChildSlot ( void  )

Definition at line 247 of file pmsignal.c.

248 {
249  int slot = next_child_inuse;
250  int n;
251 
252  /*
253  * Scan for a free slot. Notice that we trust nothing about the contents
254  * of PMSignalState, but use only postmaster-local data for this decision.
255  * We track the last slot assigned so as not to waste time repeatedly
256  * rescanning low-numbered slots.
257  */
258  for (n = num_child_inuse; n > 0; n--)
259  {
260  if (--slot < 0)
261  slot = num_child_inuse - 1;
262  if (!PMChildInUse[slot])
263  {
264  PMChildInUse[slot] = true;
266  next_child_inuse = slot;
267  return slot + 1;
268  }
269  }
270 
271  /* Out of slots ... should never happen, else postmaster.c messed up */
272  elog(FATAL, "no free slots in PMChildFlags array");
273  return 0; /* keep compiler quiet */
274 }
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:224
static bool * PMChildInUse
Definition: pmsignal.c:92
static int num_child_inuse
Definition: pmsignal.c:90
static int next_child_inuse
Definition: pmsignal.c:91
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:83
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:66
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:79

References elog, FATAL, next_child_inuse, num_child_inuse, PM_CHILD_ASSIGNED, PMSignalData::PMChildFlags, PMChildInUse, and PMSignalState.

Referenced by assign_backendlist_entry(), BackendStartup(), and StartAutovacuumWorker().

◆ CheckPostmasterSignal()

bool CheckPostmasterSignal ( PMSignalReason  reason)

Definition at line 198 of file pmsignal.c.

199 {
200  /* Careful here --- don't clear flag if we haven't seen it set */
201  if (PMSignalState->PMSignalFlags[reason])
202  {
203  PMSignalState->PMSignalFlags[reason] = false;
204  return true;
205  }
206  return false;
207 }
sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]
Definition: pmsignal.c:74

References PMSignalData::PMSignalFlags, and PMSignalState.

Referenced by process_pm_pmsignal().

◆ GetQuitSignalReason()

QuitSignalReason GetQuitSignalReason ( void  )

Definition at line 229 of file pmsignal.c.

230 {
231  /* This is called in signal handlers, so be extra paranoid. */
232  if (!IsUnderPostmaster || PMSignalState == NULL)
233  return PMQUIT_NOT_SENT;
235 }
bool IsUnderPostmaster
Definition: globals.c:117
@ PMQUIT_NOT_SENT
Definition: pmsignal.h:52
QuitSignalReason sigquit_reason
Definition: pmsignal.c:76

References IsUnderPostmaster, PMQUIT_NOT_SENT, PMSignalState, and PMSignalData::sigquit_reason.

Referenced by quickdie().

◆ IsPostmasterChildWalSender()

bool IsPostmasterChildWalSender ( int  slot)

Definition at line 307 of file pmsignal.c.

308 {
309  Assert(slot > 0 && slot <= num_child_inuse);
310  slot--;
311 
313  return true;
314  else
315  return false;
316 }
#define Assert(condition)
Definition: c.h:858
#define PM_CHILD_WALSENDER
Definition: pmsignal.c:68

References Assert, num_child_inuse, PM_CHILD_WALSENDER, PMSignalData::PMChildFlags, and PMSignalState.

Referenced by CountChildren(), and SignalSomeChildren().

◆ MarkPostmasterChildActive()

void MarkPostmasterChildActive ( void  )

Definition at line 323 of file pmsignal.c.

324 {
325  int slot = MyPMChildSlot;
326 
327  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
328  slot--;
331 }
int MyPMChildSlot
Definition: globals.c:51
#define PM_CHILD_ACTIVE
Definition: pmsignal.c:67

References Assert, MyPMChildSlot, PM_CHILD_ACTIVE, PM_CHILD_ASSIGNED, PMSignalData::PMChildFlags, and PMSignalState.

Referenced by InitProcess().

◆ MarkPostmasterChildInactive()

void MarkPostmasterChildInactive ( void  )

Definition at line 356 of file pmsignal.c.

357 {
358  int slot = MyPMChildSlot;
359 
360  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
361  slot--;
365 }

References Assert, MyPMChildSlot, PM_CHILD_ACTIVE, PM_CHILD_ASSIGNED, PM_CHILD_WALSENDER, PMSignalData::PMChildFlags, and PMSignalState.

Referenced by ProcKill().

◆ MarkPostmasterChildWalSender()

void MarkPostmasterChildWalSender ( void  )

Definition at line 339 of file pmsignal.c.

340 {
341  int slot = MyPMChildSlot;
342 
344 
345  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
346  slot--;
349 }
bool am_walsender
Definition: walsender.c:115

References am_walsender, Assert, MyPMChildSlot, PM_CHILD_ACTIVE, PM_CHILD_WALSENDER, PMSignalData::PMChildFlags, and PMSignalState.

◆ PMSignalShmemInit()

void PMSignalShmemInit ( void  )

Definition at line 144 of file pmsignal.c.

145 {
146  bool found;
147 
149  ShmemInitStruct("PMSignalState", PMSignalShmemSize(), &found);
150 
151  if (!found)
152  {
153  /* initialize all flags to zeroes */
157 
158  /*
159  * Also allocate postmaster's private PMChildInUse[] array. We
160  * might've already done that in a previous shared-memory creation
161  * cycle, in which case free the old array to avoid a leak. (Do it
162  * like this to support the possibility that MaxLivePostmasterChildren
163  * changed.) In a standalone backend, we do not need this.
164  */
165  if (PostmasterContext != NULL)
166  {
167  if (PMChildInUse)
169  PMChildInUse = (bool *)
171  num_child_inuse * sizeof(bool));
172  }
173  next_child_inuse = 0;
174  }
175 }
#define unvolatize(underlying_type, expr)
Definition: c.h:1247
#define MemSet(start, val, len)
Definition: c.h:1020
void pfree(void *pointer)
Definition: mcxt.c:1520
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1214
MemoryContext PostmasterContext
Definition: mcxt.c:151
Size PMSignalShmemSize(void)
Definition: pmsignal.c:129
int MaxLivePostmasterChildren(void)
Definition: postmaster.c:4145
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
int num_child_flags
Definition: pmsignal.c:78

References MaxLivePostmasterChildren(), MemoryContextAllocZero(), MemSet, next_child_inuse, PMSignalData::num_child_flags, num_child_inuse, pfree(), PMChildInUse, PMSignalShmemSize(), PMSignalState, PostmasterContext, ShmemInitStruct(), and unvolatize.

Referenced by CreateOrAttachShmemStructs().

◆ PMSignalShmemSize()

Size PMSignalShmemSize ( void  )

Definition at line 129 of file pmsignal.c.

130 {
131  Size size;
132 
133  size = offsetof(PMSignalData, PMChildFlags);
135  sizeof(sig_atomic_t)));
136 
137  return size;
138 }
size_t Size
Definition: c.h:605
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
static pg_noinline void Size size
Definition: slab.c:607

References add_size(), MaxLivePostmasterChildren(), mul_size(), and size.

Referenced by CalculateShmemSize(), and PMSignalShmemInit().

◆ PostmasterDeathSignalInit()

void PostmasterDeathSignalInit ( void  )

Definition at line 437 of file pmsignal.c.

438 {
439 #ifdef USE_POSTMASTER_DEATH_SIGNAL
440  int signum = POSTMASTER_DEATH_SIGNAL;
441 
442  /* Register our signal handler. */
443  pqsignal(signum, postmaster_death_handler);
444 
445  /* Request a signal on parent exit. */
446 #if defined(PR_SET_PDEATHSIG)
447  if (prctl(PR_SET_PDEATHSIG, signum) < 0)
448  elog(ERROR, "could not request parent death signal: %m");
449 #elif defined(PROC_PDEATHSIG_CTL)
450  if (procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum) < 0)
451  elog(ERROR, "could not request parent death signal: %m");
452 #else
453 #error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal"
454 #endif
455 
456  /*
457  * Just in case the parent was gone already and we missed it, we'd better
458  * check the slow way on the first call.
459  */
460  postmaster_possibly_dead = true;
461 #endif /* USE_POSTMASTER_DEATH_SIGNAL */
462 }
#define ERROR
Definition: elog.h:39
pqsigfunc pqsignal(int signo, pqsigfunc func)

References elog, ERROR, and pqsignal().

Referenced by InitPostmasterChild().

◆ PostmasterIsAliveInternal()

bool PostmasterIsAliveInternal ( void  )

Definition at line 376 of file pmsignal.c.

377 {
378 #ifdef USE_POSTMASTER_DEATH_SIGNAL
379  /*
380  * Reset the flag before checking, so that we don't miss a signal if
381  * postmaster dies right after the check. If postmaster was indeed dead,
382  * we'll re-arm it before returning to caller.
383  */
384  postmaster_possibly_dead = false;
385 #endif
386 
387 #ifndef WIN32
388  {
389  char c;
390  ssize_t rc;
391 
393 
394  /*
395  * In the usual case, the postmaster is still alive, and there is no
396  * data in the pipe.
397  */
398  if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
399  return true;
400  else
401  {
402  /*
403  * Postmaster is dead, or something went wrong with the read()
404  * call.
405  */
406 
407 #ifdef USE_POSTMASTER_DEATH_SIGNAL
408  postmaster_possibly_dead = true;
409 #endif
410 
411  if (rc < 0)
412  elog(FATAL, "read on postmaster death monitoring pipe failed: %m");
413  else if (rc > 0)
414  elog(FATAL, "unexpected data in postmaster death monitoring pipe");
415 
416  return false;
417  }
418  }
419 
420 #else /* WIN32 */
421  if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT)
422  return true;
423  else
424  {
425 #ifdef USE_POSTMASTER_DEATH_SIGNAL
426  postmaster_possibly_dead = true;
427 #endif
428  return false;
429  }
430 #endif /* WIN32 */
431 }
#define read(a, b, c)
Definition: win32.h:13
int postmaster_alive_fds[2]
Definition: postmaster.c:479
#define POSTMASTER_FD_WATCH
Definition: postmaster.h:48
char * c
#define EWOULDBLOCK
Definition: win32_port.h:380
#define EAGAIN
Definition: win32_port.h:372

References EAGAIN, elog, EWOULDBLOCK, FATAL, postmaster_alive_fds, POSTMASTER_FD_WATCH, and read.

Referenced by WaitEventSetWaitBlock().

◆ ReleasePostmasterChildSlot()

bool ReleasePostmasterChildSlot ( int  slot)

Definition at line 284 of file pmsignal.c.

285 {
286  bool result;
287 
288  Assert(slot > 0 && slot <= num_child_inuse);
289  slot--;
290 
291  /*
292  * Note: the slot state might already be unused, because the logic in
293  * postmaster.c is such that this might get called twice when a child
294  * crashes. So we don't try to Assert anything about the state.
295  */
296  result = (PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
298  PMChildInUse[slot] = false;
299  return result;
300 }
#define PM_CHILD_UNUSED
Definition: pmsignal.c:65

References Assert, num_child_inuse, PM_CHILD_ASSIGNED, PM_CHILD_UNUSED, PMSignalData::PMChildFlags, PMChildInUse, and PMSignalState.

Referenced by BackendStartup(), CleanupBackend(), CleanupBackgroundWorker(), do_start_bgworker(), HandleChildCrash(), and StartAutovacuumWorker().

◆ SendPostmasterSignal()

void SendPostmasterSignal ( PMSignalReason  reason)

Definition at line 181 of file pmsignal.c.

182 {
183  /* If called in a standalone backend, do nothing */
184  if (!IsUnderPostmaster)
185  return;
186  /* Atomically set the proper flag */
187  PMSignalState->PMSignalFlags[reason] = true;
188  /* Send signal to postmaster */
190 }
pid_t PostmasterPid
Definition: globals.c:103
#define kill(pid, sig)
Definition: win32_port.h:485
#define SIGUSR1
Definition: win32_port.h:180

References IsUnderPostmaster, kill, PMSignalData::PMSignalFlags, PMSignalState, PostmasterPid, and SIGUSR1.

Referenced by CheckRecoveryConsistency(), do_start_worker(), GetNewMultiXactId(), GetNewTransactionId(), PerformWalRecovery(), pg_rotate_logfile(), RegisterDynamicBackgroundWorker(), RequestXLogStreaming(), SetMultiXactIdLimit(), SetTransactionIdLimit(), and TerminateBackgroundWorker().

◆ SetQuitSignalReason()

void SetQuitSignalReason ( QuitSignalReason  reason)

Definition at line 218 of file pmsignal.c.

219 {
220  PMSignalState->sigquit_reason = reason;
221 }

References PMSignalState, and PMSignalData::sigquit_reason.

Referenced by HandleChildCrash(), and process_pm_shutdown_request().

Variable Documentation

◆ next_child_inuse

int next_child_inuse
static

Definition at line 91 of file pmsignal.c.

Referenced by AssignPostmasterChildSlot(), and PMSignalShmemInit().

◆ num_child_inuse

int num_child_inuse
static

◆ PMChildInUse

bool* PMChildInUse
static

◆ PMSignalState