1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-21 05:21:08 +03:00
Files
postgres/src/backend/postmaster/interrupt.c
Nathan Bossart 28e4632509 Centralize logic for restoring errno in signal handlers.
Presently, we rely on each individual signal handler to save the
initial value of errno and then restore it before returning if
needed.  This is easily forgotten and, if missed, often goes
undetected for a long time.

In commit 3b00fdba9f, we introduced a wrapper signal handler
function that checks whether MyProcPid matches getpid().  This
commit moves the aforementioned errno restoration code from the
individual signal handlers to the new wrapper handler so that we no
longer need to worry about missing it.

Reviewed-by: Andres Freund, Noah Misch
Discussion: https://postgr.es/m/20231121212008.GA3742740%40nathanxps13
2024-02-14 16:34:18 -06:00

110 lines
3.1 KiB
C

/*-------------------------------------------------------------------------
*
* interrupt.c
* Interrupt handling routines.
*
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/backend/postmaster/interrupt.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include "miscadmin.h"
#include "postmaster/interrupt.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/procsignal.h"
#include "utils/guc.h"
#include "utils/memutils.h"
volatile sig_atomic_t ConfigReloadPending = false;
volatile sig_atomic_t ShutdownRequestPending = false;
/*
* Simple interrupt handler for main loops of background processes.
*/
void
HandleMainLoopInterrupts(void)
{
if (ProcSignalBarrierPending)
ProcessProcSignalBarrier();
if (ConfigReloadPending)
{
ConfigReloadPending = false;
ProcessConfigFile(PGC_SIGHUP);
}
if (ShutdownRequestPending)
proc_exit(0);
/* Perform logging of memory contexts of this process */
if (LogMemoryContextPending)
ProcessLogMemoryContextInterrupt();
}
/*
* Simple signal handler for triggering a configuration reload.
*
* Normally, this handler would be used for SIGHUP. The idea is that code
* which uses it would arrange to check the ConfigReloadPending flag at
* convenient places inside main loops, or else call HandleMainLoopInterrupts.
*/
void
SignalHandlerForConfigReload(SIGNAL_ARGS)
{
ConfigReloadPending = true;
SetLatch(MyLatch);
}
/*
* Simple signal handler for exiting quickly as if due to a crash.
*
* Normally, this would be used for handling SIGQUIT.
*/
void
SignalHandlerForCrashExit(SIGNAL_ARGS)
{
/*
* We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
* because shared memory may be corrupted, so we don't want to try to
* clean up our transaction. Just nail the windows shut and get out of
* town. The callbacks wouldn't be safe to run from a signal handler,
* anyway.
*
* Note we do _exit(2) not _exit(0). This is to force the postmaster into
* a system reset cycle if someone sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
* shared memory state. (The "dead man switch" mechanism in pmsignal.c
* should ensure the postmaster sees this as a crash, too, but no harm in
* being doubly sure.)
*/
_exit(2);
}
/*
* Simple signal handler for triggering a long-running background process to
* shut down and exit.
*
* Typically, this handler would be used for SIGTERM, but some processes use
* other signals. In particular, the checkpointer exits on SIGUSR2, and the WAL
* writer and the logical replication parallel apply worker exits on either
* SIGINT or SIGTERM.
*
* ShutdownRequestPending should be checked at a convenient place within the
* main loop, or else the main loop should call HandleMainLoopInterrupts.
*/
void
SignalHandlerForShutdownRequest(SIGNAL_ARGS)
{
ShutdownRequestPending = true;
SetLatch(MyLatch);
}