summaryrefslogtreecommitdiff
path: root/src/backend/postmaster
diff options
context:
space:
mode:
authorRobert Haas2019-12-17 18:14:28 +0000
committerRobert Haas2019-12-17 18:14:28 +0000
commit7dbfea3c455e83a77213a92b9dfdc1c0577441ea (patch)
tree89ed47744448377a89e05a3ac2316a67c8b02fba /src/backend/postmaster
parent1e53fe0e70f610c34f4c9e770d108cd94151342c (diff)
Partially deduplicate interrupt handling for background processes.
Where possible, share signal handler code and main loop interrupt checking. This saves quite a bit of code and should simplify maintenance, too. This commit intends not to change the way anything works, even though that might allow more code to be unified. It does unify a bunch of individual variables into a ShutdownRequestPending flag that has is now used by a bunch of different process types, though. Patch by me, reviewed by Andres Freund and Daniel Gustafsson. Discussion: http://postgr.es/m/CA+TgmoZwDk=BguVDVa+qdA6SBKef=PKbaKDQALTC_9qoz1mJqg@mail.gmail.com
Diffstat (limited to 'src/backend/postmaster')
-rw-r--r--src/backend/postmaster/Makefile1
-rw-r--r--src/backend/postmaster/autovacuum.c29
-rw-r--r--src/backend/postmaster/bgworker.c25
-rw-r--r--src/backend/postmaster/bgwriter.c93
-rw-r--r--src/backend/postmaster/checkpointer.c60
-rw-r--r--src/backend/postmaster/interrupt.c108
-rw-r--r--src/backend/postmaster/pgarch.c29
-rw-r--r--src/backend/postmaster/pgstat.c28
-rw-r--r--src/backend/postmaster/startup.c34
-rw-r--r--src/backend/postmaster/walwriter.c84
10 files changed, 149 insertions, 342 deletions
diff --git a/src/backend/postmaster/Makefile b/src/backend/postmaster/Makefile
index 03e3d3650ae..bfdf6a833db 100644
--- a/src/backend/postmaster/Makefile
+++ b/src/backend/postmaster/Makefile
@@ -18,6 +18,7 @@ OBJS = \
bgwriter.o \
checkpointer.o \
fork_process.o \
+ interrupt.o \
pgarch.o \
pgstat.o \
postmaster.o \
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index b1c2b0a01c2..1792008ebe5 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -84,6 +84,7 @@
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/fork_process.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
@@ -139,7 +140,6 @@ static bool am_autovacuum_worker = false;
/* Flags set by signal handlers */
static volatile sig_atomic_t got_SIGUSR2 = false;
-static volatile sig_atomic_t got_SIGTERM = false;
/* Comparison points for determining whether freeze_max_age is exceeded */
static TransactionId recentXid;
@@ -344,7 +344,6 @@ static void autovac_report_activity(autovac_table *tab);
static void autovac_report_workitem(AutoVacuumWorkItem *workitem,
const char *nspname, const char *relname);
static void avl_sigusr2_handler(SIGNAL_ARGS);
-static void avl_sigterm_handler(SIGNAL_ARGS);
static void autovac_refresh_stats(void);
@@ -450,9 +449,9 @@ AutoVacLauncherMain(int argc, char *argv[])
* backend, so we use the same signal handling. See equivalent code in
* tcop/postgres.c.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, StatementCancelHandler);
- pqsignal(SIGTERM, avl_sigterm_handler);
+ pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
pqsignal(SIGQUIT, quickdie);
InitializeTimeouts(); /* establishes SIGALRM handler */
@@ -553,7 +552,7 @@ AutoVacLauncherMain(int argc, char *argv[])
RESUME_INTERRUPTS();
/* if in shutdown mode, no need for anything further; just go away */
- if (got_SIGTERM)
+ if (ShutdownRequestPending)
AutoVacLauncherShutdown();
/*
@@ -605,7 +604,7 @@ AutoVacLauncherMain(int argc, char *argv[])
*/
if (!AutoVacuumingActive())
{
- if (!got_SIGTERM)
+ if (!ShutdownRequestPending)
do_start_worker();
proc_exit(0); /* done */
}
@@ -622,7 +621,7 @@ AutoVacLauncherMain(int argc, char *argv[])
rebuild_database_list(InvalidOid);
/* loop until shutdown request */
- while (!got_SIGTERM)
+ while (!ShutdownRequestPending)
{
struct timeval nap;
TimestampTz current_time = 0;
@@ -800,7 +799,7 @@ static void
HandleAutoVacLauncherInterrupts(void)
{
/* the normal shutdown case */
- if (got_SIGTERM)
+ if (ShutdownRequestPending)
AutoVacLauncherShutdown();
if (ConfigReloadPending)
@@ -1415,18 +1414,6 @@ avl_sigusr2_handler(SIGNAL_ARGS)
errno = save_errno;
}
-/* SIGTERM: time to die */
-static void
-avl_sigterm_handler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- got_SIGTERM = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
-
/********************************************************************
* AUTOVACUUM WORKER CODE
@@ -1525,7 +1512,7 @@ AutoVacWorkerMain(int argc, char *argv[])
* backend, so we use the same signal handling. See equivalent code in
* tcop/postgres.c.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
/*
* SIGINT is used to signal canceling the current table's vacuum; SIGTERM
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 5f8a007e73c..a4c347d5246 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -12,14 +12,13 @@
#include "postgres.h"
-#include <unistd.h>
-
#include "access/parallel.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/atomics.h"
#include "postmaster/bgworker_internals.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
@@ -641,26 +640,6 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
return true;
}
-static void
-bgworker_quickdie(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);
-}
-
/*
* Standard SIGTERM handler for background workers
*/
@@ -754,7 +733,7 @@ StartBackgroundWorker(void)
pqsignal(SIGTERM, bgworker_die);
pqsignal(SIGHUP, SIG_IGN);
- pqsignal(SIGQUIT, bgworker_quickdie);
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
InitializeTimeouts(); /* establishes SIGALRM handler */
pqsignal(SIGPIPE, SIG_IGN);
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index bca46de6d56..9cc343b74f5 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -34,16 +34,13 @@
*/
#include "postgres.h"
-#include <signal.h>
-#include <sys/time.h>
-#include <unistd.h>
-
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
+#include "postmaster/interrupt.h"
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "storage/condition_variable.h"
@@ -86,18 +83,6 @@ int BgWriterDelay = 200;
static TimestampTz last_snapshot_ts;
static XLogRecPtr last_snapshot_lsn = InvalidXLogRecPtr;
-/*
- * Flags set by interrupt handlers for later service in the main loop.
- */
-static volatile sig_atomic_t shutdown_requested = false;
-
-static void HandleBackgroundWriterInterrupts(void);
-
-/* Signal handlers */
-
-static void bg_quickdie(SIGNAL_ARGS);
-static void ReqShutdownHandler(SIGNAL_ARGS);
-
/*
* Main entry point for bgwriter process
@@ -116,10 +101,10 @@ BackgroundWriterMain(void)
/*
* Properly accept or ignore signals that might be sent to us.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, SIG_IGN);
- pqsignal(SIGTERM, ReqShutdownHandler); /* shutdown */
- pqsignal(SIGQUIT, bg_quickdie); /* hard crash time */
+ pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
@@ -241,7 +226,7 @@ BackgroundWriterMain(void)
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
- HandleBackgroundWriterInterrupts();
+ HandleMainLoopInterrupts();
/*
* Do one cycle of dirty-buffer writing.
@@ -354,71 +339,3 @@ BackgroundWriterMain(void)
prev_hibernate = can_hibernate;
}
}
-
-/*
- * Process any new interrupts.
- */
-static void
-HandleBackgroundWriterInterrupts(void)
-{
- if (ConfigReloadPending)
- {
- ConfigReloadPending = false;
- ProcessConfigFile(PGC_SIGHUP);
- }
-
- if (shutdown_requested)
- {
- /*
- * From here on, elog(ERROR) should end with exit(1), not send
- * control back to the sigsetjmp block above
- */
- ExitOnAnyError = true;
- /* Normal exit from the bgwriter is here */
- proc_exit(0); /* done */
- }
-}
-
-
-/* --------------------------------
- * signal handler routines
- * --------------------------------
- */
-
-/*
- * bg_quickdie() occurs when signalled SIGQUIT by the postmaster.
- *
- * Some backend has bought the farm,
- * so we need to stop what we're doing and exit.
- */
-static void
-bg_quickdie(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);
-}
-
-/* SIGTERM: set flag to shutdown and exit */
-static void
-ReqShutdownHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- shutdown_requested = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 9cf91b0d35c..3f35b324c33 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -36,10 +36,7 @@
*/
#include "postgres.h"
-#include <signal.h>
#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
#include "access/xlog.h"
#include "access/xlog_internal.h"
@@ -47,6 +44,7 @@
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
+#include "postmaster/interrupt.h"
#include "replication/syncrep.h"
#include "storage/bufmgr.h"
#include "storage/condition_variable.h"
@@ -149,11 +147,6 @@ int CheckPointWarning = 30;
double CheckPointCompletionTarget = 0.5;
/*
- * Flags set by interrupt handlers for later service in the main loop.
- */
-static volatile sig_atomic_t shutdown_requested = false;
-
-/*
* Private state
*/
static bool ckpt_active = false;
@@ -176,10 +169,7 @@ static bool CompactCheckpointerRequestQueue(void);
static void UpdateSharedMemoryConfig(void);
/* Signal handlers */
-
-static void chkpt_quickdie(SIGNAL_ARGS);
static void ReqCheckpointHandler(SIGNAL_ARGS);
-static void ReqShutdownHandler(SIGNAL_ARGS);
/*
@@ -204,14 +194,14 @@ CheckpointerMain(void)
* want to wait for the backends to exit, whereupon the postmaster will
* tell us it's okay to shut down (via SIGUSR2).
*/
- pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, ReqCheckpointHandler); /* request checkpoint */
pqsignal(SIGTERM, SIG_IGN); /* ignore SIGTERM */
- pqsignal(SIGQUIT, chkpt_quickdie); /* hard crash time */
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
- pqsignal(SIGUSR2, ReqShutdownHandler); /* request shutdown */
+ pqsignal(SIGUSR2, SignalHandlerForShutdownRequest);
/*
* Reset some signals that are accepted by postmaster but not here
@@ -551,7 +541,7 @@ HandleCheckpointerInterrupts(void)
*/
UpdateSharedMemoryConfig();
}
- if (shutdown_requested)
+ if (ShutdownRequestPending)
{
/*
* From here on, elog(ERROR) should end with exit(1), not send
@@ -679,7 +669,7 @@ CheckpointWriteDelay(int flags, double progress)
* in which case we just try to catch up as quickly as possible.
*/
if (!(flags & CHECKPOINT_IMMEDIATE) &&
- !shutdown_requested &&
+ !ShutdownRequestPending &&
!ImmediateCheckpointRequested() &&
IsCheckpointOnSchedule(progress))
{
@@ -807,32 +797,6 @@ IsCheckpointOnSchedule(double progress)
* --------------------------------
*/
-/*
- * chkpt_quickdie() occurs when signalled SIGQUIT by the postmaster.
- *
- * Some backend has bought the farm,
- * so we need to stop what we're doing and exit.
- */
-static void
-chkpt_quickdie(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);
-}
-
/* SIGINT: set flag to run a normal checkpoint right away */
static void
ReqCheckpointHandler(SIGNAL_ARGS)
@@ -848,18 +812,6 @@ ReqCheckpointHandler(SIGNAL_ARGS)
errno = save_errno;
}
-/* SIGUSR2: set flag to run a shutdown checkpoint and exit */
-static void
-ReqShutdownHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- shutdown_requested = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
-
/* --------------------------------
* communication with backends
diff --git a/src/backend/postmaster/interrupt.c b/src/backend/postmaster/interrupt.c
new file mode 100644
index 00000000000..6900cd02f6f
--- /dev/null
+++ b/src/backend/postmaster/interrupt.c
@@ -0,0 +1,108 @@
+/*-------------------------------------------------------------------------
+ *
+ * interrupt.c
+ * Interrupt handling routines.
+ *
+ * Portions Copyright (c) 1996-2019, 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 "utils/guc.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 (ConfigReloadPending)
+ {
+ ConfigReloadPending = false;
+ ProcessConfigFile(PGC_SIGHUP);
+ }
+
+ if (ShutdownRequestPending)
+ proc_exit(0);
+}
+
+/*
+ * 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)
+{
+ int save_errno = errno;
+
+ ConfigReloadPending = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+
+/*
+ * 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 procesess use
+ * other signals. In particular, the checkpointer exits on SIGUSR2, the
+ * stats collector on SIGQUIT, and the WAL writer 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)
+{
+ int save_errno = errno;
+
+ ShutdownRequestPending = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 09a9c66b4b2..7824180ac7f 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -39,6 +39,7 @@
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/fork_process.h"
+#include "postmaster/interrupt.h"
#include "postmaster/pgarch.h"
#include "postmaster/postmaster.h"
#include "storage/dsm.h"
@@ -83,7 +84,6 @@ static time_t last_sigterm_time = 0;
/*
* Flags set by interrupt handlers for later service in the main loop.
*/
-static volatile sig_atomic_t got_SIGTERM = false;
static volatile sig_atomic_t wakened = false;
static volatile sig_atomic_t ready_to_stop = false;
@@ -97,7 +97,6 @@ static pid_t pgarch_forkexec(void);
NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn();
static void pgarch_exit(SIGNAL_ARGS);
-static void ArchSigTermHandler(SIGNAL_ARGS);
static void pgarch_waken(SIGNAL_ARGS);
static void pgarch_waken_stop(SIGNAL_ARGS);
static void pgarch_MainLoop(void);
@@ -227,9 +226,9 @@ PgArchiverMain(int argc, char *argv[])
* Ignore all signals usually bound to some action in the postmaster,
* except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, SIG_IGN);
- pqsignal(SIGTERM, ArchSigTermHandler);
+ pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
pqsignal(SIGQUIT, pgarch_exit);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
@@ -257,24 +256,6 @@ pgarch_exit(SIGNAL_ARGS)
exit(1);
}
-/* SIGTERM signal handler for archiver process */
-static void
-ArchSigTermHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- /*
- * The postmaster never sends us SIGTERM, so we assume that this means
- * that init is trying to shut down the whole system. If we hang around
- * too long we'll get SIGKILL'd. Set flag to prevent starting any more
- * archive commands.
- */
- got_SIGTERM = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
-
/* SIGUSR1 signal handler for archiver process */
static void
pgarch_waken(SIGNAL_ARGS)
@@ -346,7 +327,7 @@ pgarch_MainLoop(void)
* idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
* that the postmaster can start a new archiver if needed.
*/
- if (got_SIGTERM)
+ if (ShutdownRequestPending)
{
time_t curtime = time(NULL);
@@ -434,7 +415,7 @@ pgarch_ArchiverCopyLoop(void)
* command, and the second is to avoid conflicts with another
* archiver spawned by a newer postmaster.
*/
- if (got_SIGTERM || !PostmasterIsAlive())
+ if (ShutdownRequestPending || !PostmasterIsAlive())
return;
/*
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 96a9e09cedc..e9315122033 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -49,6 +49,7 @@
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/fork_process.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/walsender.h"
#include "storage/backendid.h"
@@ -262,9 +263,6 @@ static PgStat_GlobalStats globalStats;
*/
static List *pending_write_requests = NIL;
-/* Signal handler flags */
-static volatile bool need_exit = false;
-
/*
* Total time charged to functions so far in the current backend.
* We use this to help separate "self" and "other" time charges.
@@ -282,7 +280,6 @@ static pid_t pgstat_forkexec(void);
#endif
NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn();
-static void pgstat_exit(SIGNAL_ARGS);
static void pgstat_beshutdown_hook(int code, Datum arg);
static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create);
@@ -4432,10 +4429,10 @@ PgstatCollectorMain(int argc, char *argv[])
* except SIGHUP and SIGQUIT. Note we don't need a SIGUSR1 handler to
* support latch operations, because we only use a local latch.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, SIG_IGN);
pqsignal(SIGTERM, SIG_IGN);
- pqsignal(SIGQUIT, pgstat_exit);
+ pqsignal(SIGQUIT, SignalHandlerForShutdownRequest);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, SIG_IGN);
@@ -4477,14 +4474,14 @@ PgstatCollectorMain(int argc, char *argv[])
/*
* Quit if we get SIGQUIT from the postmaster.
*/
- if (need_exit)
+ if (ShutdownRequestPending)
break;
/*
* Inner loop iterates as long as we keep getting messages, or until
- * need_exit becomes set.
+ * ShutdownRequestPending becomes set.
*/
- while (!need_exit)
+ while (!ShutdownRequestPending)
{
/*
* Reload configuration if we got SIGHUP from the postmaster.
@@ -4676,19 +4673,6 @@ PgstatCollectorMain(int argc, char *argv[])
exit(0);
}
-
-/* SIGQUIT signal handler for collector process */
-static void
-pgstat_exit(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- need_exit = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
-
/*
* Subroutine to clear stats in a database entry
*
diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c
index f43e57dadb9..4f59c71f733 100644
--- a/src/backend/postmaster/startup.c
+++ b/src/backend/postmaster/startup.c
@@ -19,13 +19,11 @@
*/
#include "postgres.h"
-#include <signal.h>
-#include <unistd.h>
-
#include "access/xlog.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "postmaster/interrupt.h"
#include "postmaster/startup.h"
#include "storage/ipc.h"
#include "storage/latch.h"
@@ -50,7 +48,6 @@ static volatile sig_atomic_t promote_triggered = false;
static volatile sig_atomic_t in_restore_command = false;
/* Signal handlers */
-static void startupproc_quickdie(SIGNAL_ARGS);
static void StartupProcTriggerHandler(SIGNAL_ARGS);
static void StartupProcSigHupHandler(SIGNAL_ARGS);
@@ -60,33 +57,6 @@ static void StartupProcSigHupHandler(SIGNAL_ARGS);
* --------------------------------
*/
-/*
- * startupproc_quickdie() occurs when signalled SIGQUIT by the postmaster.
- *
- * Some backend has bought the farm,
- * so we need to stop what we're doing and exit.
- */
-static void
-startupproc_quickdie(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);
-}
-
-
/* SIGUSR2: set flag to finish recovery */
static void
StartupProcTriggerHandler(SIGNAL_ARGS)
@@ -167,7 +137,7 @@ StartupProcessMain(void)
pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */
pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */
- pqsignal(SIGQUIT, startupproc_quickdie); /* hard crash time */
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
InitializeTimeouts(); /* establishes SIGALRM handler */
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 599478530f9..38e9eb1304e 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -48,6 +48,7 @@
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "postmaster/interrupt.h"
#include "postmaster/walwriter.h"
#include "storage/bufmgr.h"
#include "storage/condition_variable.h"
@@ -78,17 +79,6 @@ int WalWriterFlushAfter = 128;
#define HIBERNATE_FACTOR 25
/*
- * Flags set by interrupt handlers for later service in the main loop.
- */
-static volatile sig_atomic_t shutdown_requested = false;
-
-static void HandleWalWriterInterrupts(void);
-
-/* Signal handlers */
-static void wal_quickdie(SIGNAL_ARGS);
-static void WalShutdownHandler(SIGNAL_ARGS);
-
-/*
* Main entry point for walwriter process
*
* This is invoked from AuxiliaryProcessMain, which has already created the
@@ -108,10 +98,10 @@ WalWriterMain(void)
* We have no particular use for SIGINT at the moment, but seems
* reasonable to treat like SIGTERM.
*/
- pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */
- pqsignal(SIGINT, WalShutdownHandler); /* request shutdown */
- pqsignal(SIGTERM, WalShutdownHandler); /* request shutdown */
- pqsignal(SIGQUIT, wal_quickdie); /* hard crash time */
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
+ pqsignal(SIGINT, SignalHandlerForShutdownRequest);
+ pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
@@ -242,7 +232,7 @@ WalWriterMain(void)
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
- HandleWalWriterInterrupts();
+ HandleMainLoopInterrupts();
/*
* Do what we're here for; then, if XLogBackgroundFlush() found useful
@@ -269,65 +259,3 @@ WalWriterMain(void)
WAIT_EVENT_WAL_WRITER_MAIN);
}
}
-
-/*
- * Process any new interrupts.
- */
-static void
-HandleWalWriterInterrupts(void)
-{
- if (ConfigReloadPending)
- {
- ConfigReloadPending = false;
- ProcessConfigFile(PGC_SIGHUP);
- }
- if (shutdown_requested)
- {
- /* Normal exit from the walwriter is here */
- proc_exit(0); /* done */
- }
-}
-
-
-/* --------------------------------
- * signal handler routines
- * --------------------------------
- */
-
-/*
- * wal_quickdie() occurs when signalled SIGQUIT by the postmaster.
- *
- * Some backend has bought the farm,
- * so we need to stop what we're doing and exit.
- */
-static void
-wal_quickdie(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);
-}
-
-/* SIGTERM: set flag to exit normally */
-static void
-WalShutdownHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- shutdown_requested = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}