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 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)
 
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
 

Macro Definition Documentation

◆ PM_CHILD_ACTIVE

#define PM_CHILD_ACTIVE   2

◆ PM_CHILD_ASSIGNED

#define PM_CHILD_ASSIGNED   1

◆ PM_CHILD_UNUSED

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

Definition at line 60 of file pmsignal.c.

Referenced by AssignPostmasterChildSlot(), and ReleasePostmasterChildSlot().

◆ PM_CHILD_WALSENDER

#define PM_CHILD_WALSENDER   3

Function Documentation

◆ AssignPostmasterChildSlot()

int AssignPostmasterChildSlot ( void  )

Definition at line 184 of file pmsignal.c.

References elog, FATAL, PMSignalData::next_child_flag, PMSignalData::num_child_flags, PM_CHILD_ASSIGNED, PM_CHILD_UNUSED, PMSignalData::PMChildFlags, and PMSignalState.

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

185 {
186  int slot = PMSignalState->next_child_flag;
187  int n;
188 
189  /*
190  * Scan for a free slot. We track the last slot assigned so as not to
191  * waste time repeatedly rescanning low-numbered slots.
192  */
193  for (n = PMSignalState->num_child_flags; n > 0; n--)
194  {
195  if (--slot < 0)
196  slot = PMSignalState->num_child_flags - 1;
198  {
201  return slot + 1;
202  }
203  }
204 
205  /* Out of slots ... should never happen, else postmaster.c messed up */
206  elog(FATAL, "no free slots in PMChildFlags array");
207  return 0; /* keep compiler quiet */
208 }
int next_child_flag
Definition: pmsignal.c:72
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:61
int num_child_flags
Definition: pmsignal.c:71
#define FATAL
Definition: elog.h:52
#define PM_CHILD_UNUSED
Definition: pmsignal.c:60
#define elog(elevel,...)
Definition: elog.h:226
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73

◆ CheckPostmasterSignal()

bool CheckPostmasterSignal ( PMSignalReason  reason)

Definition at line 163 of file pmsignal.c.

References PMSignalData::PMSignalFlags, and PMSignalState.

Referenced by sigusr1_handler().

164 {
165  /* Careful here --- don't clear flag if we haven't seen it set */
166  if (PMSignalState->PMSignalFlags[reason])
167  {
168  PMSignalState->PMSignalFlags[reason] = false;
169  return true;
170  }
171  return false;
172 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]
Definition: pmsignal.c:69

◆ IsPostmasterChildWalSender()

bool IsPostmasterChildWalSender ( int  slot)

Definition at line 240 of file pmsignal.c.

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

Referenced by CountChildren(), and SignalSomeChildren().

241 {
242  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
243  slot--;
244 
246  return true;
247  else
248  return false;
249 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define Assert(condition)
Definition: c.h:732
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73
#define PM_CHILD_WALSENDER
Definition: pmsignal.c:63

◆ MarkPostmasterChildActive()

void MarkPostmasterChildActive ( void  )

Definition at line 256 of file pmsignal.c.

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

Referenced by InitProcess().

257 {
258  int slot = MyPMChildSlot;
259 
260  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
261  slot--;
264 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define PM_CHILD_ACTIVE
Definition: pmsignal.c:62
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:61
#define Assert(condition)
Definition: c.h:732
int MyPMChildSlot
Definition: globals.c:45
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73

◆ MarkPostmasterChildInactive()

void MarkPostmasterChildInactive ( void  )

Definition at line 289 of file pmsignal.c.

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

Referenced by ProcKill().

290 {
291  int slot = MyPMChildSlot;
292 
293  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
294  slot--;
298 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define PM_CHILD_ACTIVE
Definition: pmsignal.c:62
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:61
#define Assert(condition)
Definition: c.h:732
int MyPMChildSlot
Definition: globals.c:45
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73
#define PM_CHILD_WALSENDER
Definition: pmsignal.c:63

◆ MarkPostmasterChildWalSender()

void MarkPostmasterChildWalSender ( void  )

Definition at line 272 of file pmsignal.c.

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

273 {
274  int slot = MyPMChildSlot;
275 
277 
278  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
279  slot--;
282 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define PM_CHILD_ACTIVE
Definition: pmsignal.c:62
bool am_walsender
Definition: walsender.c:114
#define Assert(condition)
Definition: c.h:732
int MyPMChildSlot
Definition: globals.c:45
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73
#define PM_CHILD_WALSENDER
Definition: pmsignal.c:63

◆ PMSignalShmemInit()

void PMSignalShmemInit ( void  )

Definition at line 128 of file pmsignal.c.

References MaxLivePostmasterChildren(), MemSet, PMSignalData::num_child_flags, PMSignalShmemSize(), PMSignalState, ShmemInitStruct(), and unvolatize.

Referenced by CreateSharedMemoryAndSemaphores().

129 {
130  bool found;
131 
133  ShmemInitStruct("PMSignalState", PMSignalShmemSize(), &found);
134 
135  if (!found)
136  {
139  }
140 }
Size PMSignalShmemSize(void)
Definition: pmsignal.c:113
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define MemSet(start, val, len)
Definition: c.h:955
int num_child_flags
Definition: pmsignal.c:71
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:372
int MaxLivePostmasterChildren(void)
Definition: postmaster.c:5675
#define unvolatize(underlying_type, expr)
Definition: c.h:1165

◆ PMSignalShmemSize()

Size PMSignalShmemSize ( void  )

Definition at line 113 of file pmsignal.c.

References add_size(), MaxLivePostmasterChildren(), mul_size(), offsetof, and PMSignalData::PMChildFlags.

Referenced by CreateSharedMemoryAndSemaphores(), and PMSignalShmemInit().

114 {
115  Size size;
116 
117  size = offsetof(PMSignalData, PMChildFlags);
119  sizeof(sig_atomic_t)));
120 
121  return size;
122 }
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
int MaxLivePostmasterChildren(void)
Definition: postmaster.c:5675
size_t Size
Definition: c.h:466
#define offsetof(type, field)
Definition: c.h:655

◆ PostmasterDeathSignalInit()

void PostmasterDeathSignalInit ( void  )

Definition at line 370 of file pmsignal.c.

References elog, ERROR, and pqsignal().

Referenced by InitPostmasterChild().

371 {
372 #ifdef USE_POSTMASTER_DEATH_SIGNAL
373  int signum = POSTMASTER_DEATH_SIGNAL;
374 
375  /* Register our signal handler. */
376  pqsignal(signum, postmaster_death_handler);
377 
378  /* Request a signal on parent exit. */
379 #if defined(PR_SET_PDEATHSIG)
380  if (prctl(PR_SET_PDEATHSIG, signum) < 0)
381  elog(ERROR, "could not request parent death signal: %m");
382 #elif defined(PROC_PDEATHSIG_CTL)
383  if (procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum) < 0)
384  elog(ERROR, "could not request parent death signal: %m");
385 #else
386 #error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal"
387 #endif
388 
389  /*
390  * Just in case the parent was gone already and we missed it, we'd better
391  * check the slow way on the first call.
392  */
393  postmaster_possibly_dead = true;
394 #endif /* USE_POSTMASTER_DEATH_SIGNAL */
395 }
#define ERROR
Definition: elog.h:43
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define elog(elevel,...)
Definition: elog.h:226

◆ PostmasterIsAliveInternal()

bool PostmasterIsAliveInternal ( void  )

Definition at line 309 of file pmsignal.c.

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

Referenced by WaitEventSetWait().

310 {
311 #ifdef USE_POSTMASTER_DEATH_SIGNAL
312  /*
313  * Reset the flag before checking, so that we don't miss a signal if
314  * postmaster dies right after the check. If postmaster was indeed dead,
315  * we'll re-arm it before returning to caller.
316  */
317  postmaster_possibly_dead = false;
318 #endif
319 
320 #ifndef WIN32
321  {
322  char c;
323  ssize_t rc;
324 
326 
327  /*
328  * In the usual case, the postmaster is still alive, and there is no
329  * data in the pipe.
330  */
331  if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
332  return true;
333  else
334  {
335  /*
336  * Postmaster is dead, or something went wrong with the read()
337  * call.
338  */
339 
340 #ifdef USE_POSTMASTER_DEATH_SIGNAL
341  postmaster_possibly_dead = true;
342 #endif
343 
344  if (rc < 0)
345  elog(FATAL, "read on postmaster death monitoring pipe failed: %m");
346  else if (rc > 0)
347  elog(FATAL, "unexpected data in postmaster death monitoring pipe");
348 
349  return false;
350  }
351  }
352 
353 #else /* WIN32 */
354  if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT)
355  return true;
356  else
357  {
358 #ifdef USE_POSTMASTER_DEATH_SIGNAL
359  postmaster_possibly_dead = true;
360 #endif
361  return false;
362  }
363 #endif /* WIN32 */
364 }
#define EAGAIN
Definition: win32_port.h:321
#define FATAL
Definition: elog.h:52
char * c
int postmaster_alive_fds[2]
Definition: postmaster.c:557
#define elog(elevel,...)
Definition: elog.h:226
#define EWOULDBLOCK
Definition: win32_port.h:329
#define POSTMASTER_FD_WATCH
Definition: postmaster.h:42
#define read(a, b, c)
Definition: win32.h:13

◆ ReleasePostmasterChildSlot()

bool ReleasePostmasterChildSlot ( int  slot)

Definition at line 218 of file pmsignal.c.

References Assert, PMSignalData::num_child_flags, PM_CHILD_ASSIGNED, PM_CHILD_UNUSED, PMSignalData::PMChildFlags, and PMSignalState.

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

219 {
220  bool result;
221 
222  Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
223  slot--;
224 
225  /*
226  * Note: the slot state might already be unused, because the logic in
227  * postmaster.c is such that this might get called twice when a child
228  * crashes. So we don't try to Assert anything about the state.
229  */
230  result = (PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
232  return result;
233 }
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:61
#define Assert(condition)
Definition: c.h:732
#define PM_CHILD_UNUSED
Definition: pmsignal.c:60
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:73

◆ SendPostmasterSignal()

void SendPostmasterSignal ( PMSignalReason  reason)

Definition at line 146 of file pmsignal.c.

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

Referenced by AutoVacLauncherMain(), CheckRecoveryConsistency(), do_start_worker(), GetNewMultiXactId(), GetNewTransactionId(), pg_rotate_logfile(), pg_rotate_logfile_v2(), RegisterDynamicBackgroundWorker(), RequestXLogStreaming(), SetMultiXactIdLimit(), SetTransactionIdLimit(), StartupXLOG(), TerminateBackgroundWorker(), and XLogArchiveNotify().

147 {
148  /* If called in a standalone backend, do nothing */
149  if (!IsUnderPostmaster)
150  return;
151  /* Atomically set the proper flag */
152  PMSignalState->PMSignalFlags[reason] = true;
153  /* Send signal to postmaster */
155 }
#define SIGUSR1
Definition: win32_port.h:166
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:76
#define kill(pid, sig)
Definition: win32_port.h:426
bool IsUnderPostmaster
Definition: globals.c:109
pid_t PostmasterPid
Definition: globals.c:95
sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]
Definition: pmsignal.c:69

Variable Documentation

◆ PMSignalState