1 /*-------------------------------------------------------------------------
2 *
3 * interrupt.c
4 * Interrupt handling routines.
5 *
6 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/backend/postmaster/interrupt.c
11 *
12 *-------------------------------------------------------------------------
13 */
14
15 #include "postgres.h"
16
17 #include <unistd.h>
18
19 #include "miscadmin.h"
20 #include "postmaster/interrupt.h"
21 #include "storage/ipc.h"
22 #include "storage/latch.h"
23 #include "storage/procsignal.h"
24 #include "utils/guc.h"
25
26 volatile sig_atomic_t ConfigReloadPending = false;
27 volatile sig_atomic_t ShutdownRequestPending = false;
28
29 /*
30 * Simple interrupt handler for main loops of background processes.
31 */
32 void
HandleMainLoopInterrupts(void)33 HandleMainLoopInterrupts(void)
34 {
35 if (ProcSignalBarrierPending)
36 ProcessProcSignalBarrier();
37
38 if (ConfigReloadPending)
39 {
40 ConfigReloadPending = false;
41 ProcessConfigFile(PGC_SIGHUP);
42 }
43
44 if (ShutdownRequestPending)
45 proc_exit(0);
46 }
47
48 /*
49 * Simple signal handler for triggering a configuration reload.
50 *
51 * Normally, this handler would be used for SIGHUP. The idea is that code
52 * which uses it would arrange to check the ConfigReloadPending flag at
53 * convenient places inside main loops, or else call HandleMainLoopInterrupts.
54 */
55 void
SignalHandlerForConfigReload(SIGNAL_ARGS)56 SignalHandlerForConfigReload(SIGNAL_ARGS)
57 {
58 int save_errno = errno;
59
60 ConfigReloadPending = true;
61 SetLatch(MyLatch);
62
63 errno = save_errno;
64 }
65
66 /*
67 * Simple signal handler for exiting quickly as if due to a crash.
68 *
69 * Normally, this would be used for handling SIGQUIT.
70 */
71 void
SignalHandlerForCrashExit(SIGNAL_ARGS)72 SignalHandlerForCrashExit(SIGNAL_ARGS)
73 {
74 /*
75 * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
76 * because shared memory may be corrupted, so we don't want to try to
77 * clean up our transaction. Just nail the windows shut and get out of
78 * town. The callbacks wouldn't be safe to run from a signal handler,
79 * anyway.
80 *
81 * Note we do _exit(2) not _exit(0). This is to force the postmaster into
82 * a system reset cycle if someone sends a manual SIGQUIT to a random
83 * backend. This is necessary precisely because we don't clean up our
84 * shared memory state. (The "dead man switch" mechanism in pmsignal.c
85 * should ensure the postmaster sees this as a crash, too, but no harm in
86 * being doubly sure.)
87 */
88 _exit(2);
89 }
90
91 /*
92 * Simple signal handler for triggering a long-running background process to
93 * shut down and exit.
94 *
95 * Typically, this handler would be used for SIGTERM, but some processes use
96 * other signals. In particular, the checkpointer exits on SIGUSR2, the
97 * stats collector on SIGQUIT, and the WAL writer exits on either SIGINT
98 * or SIGTERM.
99 *
100 * ShutdownRequestPending should be checked at a convenient place within the
101 * main loop, or else the main loop should call HandleMainLoopInterrupts.
102 */
103 void
SignalHandlerForShutdownRequest(SIGNAL_ARGS)104 SignalHandlerForShutdownRequest(SIGNAL_ARGS)
105 {
106 int save_errno = errno;
107
108 ShutdownRequestPending = true;
109 SetLatch(MyLatch);
110
111 errno = save_errno;
112 }
113