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/ipc.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

static void MarkPostmasterChildInactive (int code, Datum arg)
 
Size PMSignalShmemSize (void)
 
void PMSignalShmemInit (void)
 
void SendPostmasterSignal (PMSignalReason reason)
 
bool CheckPostmasterSignal (PMSignalReason reason)
 
void SetQuitSignalReason (QuitSignalReason reason)
 
QuitSignalReason GetQuitSignalReason (void)
 
void MarkPostmasterChildSlotAssigned (int slot)
 
bool MarkPostmasterChildSlotUnassigned (int slot)
 
bool IsPostmasterChildWalSender (int slot)
 
void RegisterPostmasterChildActive (void)
 
void MarkPostmasterChildWalSender (void)
 
bool PostmasterIsAliveInternal (void)
 
void PostmasterDeathSignalInit (void)
 

Variables

NON_EXEC_STATIC volatile PMSignalDataPMSignalState = NULL
 
static int num_child_flags
 

Macro Definition Documentation

◆ PM_CHILD_ACTIVE

#define PM_CHILD_ACTIVE   2

Definition at line 68 of file pmsignal.c.

◆ PM_CHILD_ASSIGNED

#define PM_CHILD_ASSIGNED   1

Definition at line 67 of file pmsignal.c.

◆ PM_CHILD_UNUSED

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

Definition at line 66 of file pmsignal.c.

◆ PM_CHILD_WALSENDER

#define PM_CHILD_WALSENDER   3

Definition at line 69 of file pmsignal.c.

Function Documentation

◆ CheckPostmasterSignal()

bool CheckPostmasterSignal ( PMSignalReason  reason)

Definition at line 182 of file pmsignal.c.

183{
184 /* Careful here --- don't clear flag if we haven't seen it set */
185 if (PMSignalState->PMSignalFlags[reason])
186 {
187 PMSignalState->PMSignalFlags[reason] = false;
188 return true;
189 }
190 return false;
191}
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
Definition: pmsignal.c:84
sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]
Definition: pmsignal.c:75

References PMSignalData::PMSignalFlags, and PMSignalState.

Referenced by process_pm_pmsignal().

◆ GetQuitSignalReason()

QuitSignalReason GetQuitSignalReason ( void  )

Definition at line 213 of file pmsignal.c.

214{
215 /* This is called in signal handlers, so be extra paranoid. */
216 if (!IsUnderPostmaster || PMSignalState == NULL)
217 return PMQUIT_NOT_SENT;
219}
bool IsUnderPostmaster
Definition: globals.c:119
@ PMQUIT_NOT_SENT
Definition: pmsignal.h:53
QuitSignalReason sigquit_reason
Definition: pmsignal.c:77

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

Referenced by quickdie().

◆ IsPostmasterChildWalSender()

bool IsPostmasterChildWalSender ( int  slot)

Definition at line 271 of file pmsignal.c.

272{
273 Assert(slot > 0 && slot <= num_child_flags);
274 slot--;
275
277 return true;
278 else
279 return false;
280}
#define Assert(condition)
Definition: c.h:815
#define PM_CHILD_WALSENDER
Definition: pmsignal.c:69
static int num_child_flags
Definition: pmsignal.c:91
sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]
Definition: pmsignal.c:80

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

Referenced by CountChildren(), and SignalChildren().

◆ MarkPostmasterChildInactive()

static void MarkPostmasterChildInactive ( int  code,
Datum  arg 
)
static

Definition at line 326 of file pmsignal.c.

327{
328 int slot = MyPMChildSlot;
329
330 Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
331 slot--;
335}
int MyPMChildSlot
Definition: globals.c:53
#define PM_CHILD_ACTIVE
Definition: pmsignal.c:68
#define PM_CHILD_ASSIGNED
Definition: pmsignal.c:67

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

Referenced by RegisterPostmasterChildActive().

◆ MarkPostmasterChildSlotAssigned()

void MarkPostmasterChildSlotAssigned ( int  slot)

Definition at line 230 of file pmsignal.c.

231{
232 Assert(slot > 0 && slot <= num_child_flags);
233 slot--;
234
236 elog(FATAL, "postmaster child slot is already in use");
237
239}
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:225
#define PM_CHILD_UNUSED
Definition: pmsignal.c:66

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

Referenced by AssignPostmasterChildSlot().

◆ MarkPostmasterChildSlotUnassigned()

bool MarkPostmasterChildSlotUnassigned ( int  slot)

Definition at line 249 of file pmsignal.c.

250{
251 bool result;
252
253 Assert(slot > 0 && slot <= num_child_flags);
254 slot--;
255
256 /*
257 * Note: the slot state might already be unused, because the logic in
258 * postmaster.c is such that this might get called twice when a child
259 * crashes. So we don't try to Assert anything about the state.
260 */
261 result = (PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
263 return result;
264}

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

Referenced by ReleasePostmasterChildSlot().

◆ MarkPostmasterChildWalSender()

void MarkPostmasterChildWalSender ( void  )

Definition at line 309 of file pmsignal.c.

310{
311 int slot = MyPMChildSlot;
312
314
315 Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
316 slot--;
319}
bool am_walsender
Definition: walsender.c:115

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

◆ PMSignalShmemInit()

void PMSignalShmemInit ( void  )

Definition at line 145 of file pmsignal.c.

146{
147 bool found;
148
150 ShmemInitStruct("PMSignalState", PMSignalShmemSize(), &found);
151
152 if (!found)
153 {
154 /* initialize all flags to zeroes */
158 }
159}
#define unvolatize(underlying_type, expr)
Definition: c.h:1204
#define MemSet(start, val, len)
Definition: c.h:977
int MaxLivePostmasterChildren(void)
Definition: pmchild.c:70
Size PMSignalShmemSize(void)
Definition: pmsignal.c:130
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:382
int num_child_flags
Definition: pmsignal.c:79

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

Referenced by CreateOrAttachShmemStructs().

◆ PMSignalShmemSize()

Size PMSignalShmemSize ( void  )

Definition at line 130 of file pmsignal.c.

131{
132 Size size;
133
134 size = offsetof(PMSignalData, PMChildFlags);
136 sizeof(sig_atomic_t)));
137
138 return size;
139}
size_t Size
Definition: c.h:562
Size add_size(Size s1, Size s2)
Definition: shmem.c:488
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505
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 407 of file pmsignal.c.

408{
409#ifdef USE_POSTMASTER_DEATH_SIGNAL
410 int signum = POSTMASTER_DEATH_SIGNAL;
411
412 /* Register our signal handler. */
413 pqsignal(signum, postmaster_death_handler);
414
415 /* Request a signal on parent exit. */
416#if defined(PR_SET_PDEATHSIG)
417 if (prctl(PR_SET_PDEATHSIG, signum) < 0)
418 elog(ERROR, "could not request parent death signal: %m");
419#elif defined(PROC_PDEATHSIG_CTL)
420 if (procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum) < 0)
421 elog(ERROR, "could not request parent death signal: %m");
422#else
423#error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal"
424#endif
425
426 /*
427 * Just in case the parent was gone already and we missed it, we'd better
428 * check the slow way on the first call.
429 */
430 postmaster_possibly_dead = true;
431#endif /* USE_POSTMASTER_DEATH_SIGNAL */
432}
#define ERROR
Definition: elog.h:39
#define pqsignal
Definition: port.h:521

References elog, ERROR, and pqsignal.

Referenced by InitPostmasterChild().

◆ PostmasterIsAliveInternal()

bool PostmasterIsAliveInternal ( void  )

Definition at line 346 of file pmsignal.c.

347{
348#ifdef USE_POSTMASTER_DEATH_SIGNAL
349 /*
350 * Reset the flag before checking, so that we don't miss a signal if
351 * postmaster dies right after the check. If postmaster was indeed dead,
352 * we'll re-arm it before returning to caller.
353 */
354 postmaster_possibly_dead = false;
355#endif
356
357#ifndef WIN32
358 {
359 char c;
360 ssize_t rc;
361
363
364 /*
365 * In the usual case, the postmaster is still alive, and there is no
366 * data in the pipe.
367 */
368 if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
369 return true;
370 else
371 {
372 /*
373 * Postmaster is dead, or something went wrong with the read()
374 * call.
375 */
376
377#ifdef USE_POSTMASTER_DEATH_SIGNAL
378 postmaster_possibly_dead = true;
379#endif
380
381 if (rc < 0)
382 elog(FATAL, "read on postmaster death monitoring pipe failed: %m");
383 else if (rc > 0)
384 elog(FATAL, "unexpected data in postmaster death monitoring pipe");
385
386 return false;
387 }
388 }
389
390#else /* WIN32 */
391 if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT)
392 return true;
393 else
394 {
395#ifdef USE_POSTMASTER_DEATH_SIGNAL
396 postmaster_possibly_dead = true;
397#endif
398 return false;
399 }
400#endif /* WIN32 */
401}
#define read(a, b, c)
Definition: win32.h:13
int postmaster_alive_fds[2]
Definition: postmaster.c:473
#define POSTMASTER_FD_WATCH
Definition: postmaster.h:84
char * c
#define EWOULDBLOCK
Definition: win32_port.h:370
#define EAGAIN
Definition: win32_port.h:362

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

Referenced by WaitEventSetWaitBlock().

◆ RegisterPostmasterChildActive()

void RegisterPostmasterChildActive ( void  )

Definition at line 290 of file pmsignal.c.

291{
292 int slot = MyPMChildSlot;
293
294 Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
295 slot--;
298
299 /* Arrange to clean up at exit. */
301}
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
static void MarkPostmasterChildInactive(int code, Datum arg)
Definition: pmsignal.c:326

References Assert, MarkPostmasterChildInactive(), MyPMChildSlot, num_child_flags, on_shmem_exit(), PM_CHILD_ACTIVE, PM_CHILD_ASSIGNED, PMSignalData::PMChildFlags, and PMSignalState.

Referenced by InitAuxiliaryProcess(), and InitProcess().

◆ SendPostmasterSignal()

void SendPostmasterSignal ( PMSignalReason  reason)

Definition at line 165 of file pmsignal.c.

166{
167 /* If called in a standalone backend, do nothing */
169 return;
170 /* Atomically set the proper flag */
171 PMSignalState->PMSignalFlags[reason] = true;
172 /* Send signal to postmaster */
174}
pid_t PostmasterPid
Definition: globals.c:105
#define kill(pid, sig)
Definition: win32_port.h:493
#define SIGUSR1
Definition: win32_port.h:170

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

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

◆ SetQuitSignalReason()

void SetQuitSignalReason ( QuitSignalReason  reason)

Definition at line 202 of file pmsignal.c.

203{
205}

References PMSignalState, and PMSignalData::sigquit_reason.

Referenced by HandleFatalError(), and process_pm_shutdown_request().

Variable Documentation

◆ num_child_flags

◆ PMSignalState