aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/backend/replication/logical/launcher.c3
-rw-r--r--src/backend/replication/logical/worker.c3
-rw-r--r--src/backend/replication/walreceiver.c31
-rw-r--r--src/backend/replication/walsender.c4
-rw-r--r--src/backend/tcop/postgres.c22
-rw-r--r--src/backend/utils/init/globals.c1
-rw-r--r--src/include/miscadmin.h3
-rw-r--r--src/include/postmaster/interrupt.h32
18 files changed, 191 insertions, 399 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;
-}
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index edca70c58c3..99cfa5d8b49 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -30,6 +30,7 @@
#include "pgstat.h"
#include "postmaster/bgworker.h"
#include "postmaster/fork_process.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
@@ -955,7 +956,7 @@ ApplyLauncherMain(Datum main_arg)
LogicalRepCtx->launcher_pid = MyProcPid;
/* Establish signal handlers. */
- pqsignal(SIGTERM, PostgresSigHupHandler);
+ pqsignal(SIGTERM, SignalHandlerForConfigReload);
pqsignal(SIGTERM, die);
BackgroundWorkerUnblockSignals();
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 3b12ad64006..4bf6f5e4271 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -45,6 +45,7 @@
#include "parser/parse_relation.h"
#include "pgstat.h"
#include "postmaster/bgworker.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "postmaster/walwriter.h"
#include "replication/decode.h"
@@ -1575,7 +1576,7 @@ ApplyWorkerMain(Datum main_arg)
logicalrep_worker_attach(worker_slot);
/* Setup signal handling */
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGTERM, die);
BackgroundWorkerUnblockSignals();
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index c1e439adb40..c36bcc08ec7 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -43,7 +43,6 @@
*/
#include "postgres.h"
-#include <signal.h>
#include <unistd.h>
#include "access/htup_details.h"
@@ -58,6 +57,7 @@
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "postmaster/interrupt.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/ipc.h"
@@ -127,7 +127,6 @@ static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime);
/* Signal handlers */
static void WalRcvSigHupHandler(SIGNAL_ARGS);
static void WalRcvShutdownHandler(SIGNAL_ARGS);
-static void WalRcvQuickDieHandler(SIGNAL_ARGS);
/*
@@ -249,7 +248,7 @@ WalReceiverMain(void)
pqsignal(SIGHUP, WalRcvSigHupHandler); /* set flag to read config file */
pqsignal(SIGINT, SIG_IGN);
pqsignal(SIGTERM, WalRcvShutdownHandler); /* request shutdown */
- pqsignal(SIGQUIT, WalRcvQuickDieHandler); /* hard crash time */
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
@@ -781,32 +780,6 @@ WalRcvShutdownHandler(SIGNAL_ARGS)
}
/*
- * WalRcvQuickDieHandler() 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
-WalRcvQuickDieHandler(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 use _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);
-}
-
-/*
* Accept the message from XLOG stream, and process it.
*/
static void
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 8b2a2be1c07..8e74177de44 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -66,6 +66,7 @@
#include "miscadmin.h"
#include "nodes/replnodes.h"
#include "pgstat.h"
+#include "postmaster/interrupt.h"
#include "replication/basebackup.h"
#include "replication/decode.h"
#include "replication/logical.h"
@@ -2969,8 +2970,7 @@ void
WalSndSignals(void)
{
/* Set up signal handlers */
- pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config
- * file */
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, StatementCancelHandler); /* query cancel */
pqsignal(SIGTERM, die); /* request shutdown */
pqsignal(SIGQUIT, quickdie); /* hard crash time */
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0b7bc1fd030..ef5a9529689 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -58,6 +58,7 @@
#include "pg_trace.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
+#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
@@ -2862,24 +2863,6 @@ FloatExceptionHandler(SIGNAL_ARGS)
}
/*
- * SIGHUP: set flag to re-read config file at next convenient time.
- *
- * Sets the ConfigReloadPending flag, which should be checked at convenient
- * places inside main loops. (Better than doing the reading in the signal
- * handler, ey?)
- */
-void
-PostgresSigHupHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- ConfigReloadPending = true;
- SetLatch(MyLatch);
-
- errno = save_errno;
-}
-
-/*
* RecoveryConflictInterrupt: out-of-line portion of recovery conflict
* handling following receipt of SIGUSR1. Designed to be similar to die()
* and StatementCancelHandler(). Called only by a normal user backend
@@ -3827,8 +3810,7 @@ PostgresMain(int argc, char *argv[],
WalSndSignals();
else
{
- pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config
- * file */
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGINT, StatementCancelHandler); /* cancel current query */
pqsignal(SIGTERM, die); /* cancel current query and exit */
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 3bf96de256d..4473e18e538 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -32,7 +32,6 @@ volatile sig_atomic_t QueryCancelPending = false;
volatile sig_atomic_t ProcDiePending = false;
volatile sig_atomic_t ClientConnectionLost = false;
volatile sig_atomic_t IdleInTransactionSessionTimeoutPending = false;
-volatile sig_atomic_t ConfigReloadPending = false;
volatile uint32 InterruptHoldoffCount = 0;
volatile uint32 QueryCancelHoldoffCount = 0;
volatile uint32 CritSectionCount = 0;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index bc6e03fbc7e..24f43ad6861 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -82,7 +82,6 @@ extern PGDLLIMPORT volatile sig_atomic_t InterruptPending;
extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending;
extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending;
extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending;
-extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending;
extern PGDLLIMPORT volatile sig_atomic_t ClientConnectionLost;
@@ -279,8 +278,6 @@ extern void restore_stack_base(pg_stack_base_t base);
extern void check_stack_depth(void);
extern bool stack_is_too_deep(void);
-extern void PostgresSigHupHandler(SIGNAL_ARGS);
-
/* in tcop/utility.c */
extern void PreventCommandIfReadOnly(const char *cmdname);
extern void PreventCommandIfParallelMode(const char *cmdname);
diff --git a/src/include/postmaster/interrupt.h b/src/include/postmaster/interrupt.h
new file mode 100644
index 00000000000..8f4e43be200
--- /dev/null
+++ b/src/include/postmaster/interrupt.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * interrupt.h
+ * Interrupt handling routines.
+ *
+ * Responses to interrupts are fairly varied and many types of backends
+ * have their own implementations, but we provide a few generic things
+ * here to facilitate code reuse.
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/include/postmaster/interrupt.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef INTERRUPT_H
+#define INTERRUPT_H
+
+#include <signal.h>
+
+extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending;
+extern PGDLLIMPORT volatile sig_atomic_t ShutdownRequestPending;
+
+extern void HandleMainLoopInterrupts(void);
+extern void SignalHandlerForConfigReload(SIGNAL_ARGS);
+extern void SignalHandlerForCrashExit(SIGNAL_ARGS);
+extern void SignalHandlerForShutdownRequest(SIGNAL_ARGS);
+
+#endif