bgwriter.o \
checkpointer.o \
fork_process.o \
+ interrupt.o \
pgarch.o \
pgstat.o \
postmaster.o \
#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"
/* 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;
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);
* 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 */
RESUME_INTERRUPTS();
/* if in shutdown mode, no need for anything further; just go away */
- if (got_SIGTERM)
+ if (ShutdownRequestPending)
AutoVacLauncherShutdown();
/*
*/
if (!AutoVacuumingActive())
{
- if (!got_SIGTERM)
+ if (!ShutdownRequestPending)
do_start_worker();
proc_exit(0); /* done */
}
rebuild_database_list(InvalidOid);
/* loop until shutdown request */
- while (!got_SIGTERM)
+ while (!ShutdownRequestPending)
{
struct timeval nap;
TimestampTz current_time = 0;
HandleAutoVacLauncherInterrupts(void)
{
/* the normal shutdown case */
- if (got_SIGTERM)
+ if (ShutdownRequestPending)
AutoVacLauncherShutdown();
if (ConfigReloadPending)
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
* 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
#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"
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
*/
pqsignal(SIGTERM, bgworker_die);
pqsignal(SIGHUP, SIG_IGN);
- pqsignal(SIGQUIT, bgworker_quickdie);
+ pqsignal(SIGQUIT, SignalHandlerForCrashExit);
InitializeTimeouts(); /* establishes SIGALRM handler */
pqsignal(SIGPIPE, SIG_IGN);
*/
#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"
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
/*
* 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);
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
- HandleBackgroundWriterInterrupts();
+ HandleMainLoopInterrupts();
/*
* Do one cycle of dirty-buffer writing.
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;
-}
*/
#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"
#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"
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 void UpdateSharedMemoryConfig(void);
/* Signal handlers */
-
-static void chkpt_quickdie(SIGNAL_ARGS);
static void ReqCheckpointHandler(SIGNAL_ARGS);
-static void ReqShutdownHandler(SIGNAL_ARGS);
/*
* 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
*/
UpdateSharedMemoryConfig();
}
- if (shutdown_requested)
+ if (ShutdownRequestPending)
{
/*
* From here on, elog(ERROR) should end with exit(1), not send
* in which case we just try to catch up as quickly as possible.
*/
if (!(flags & CHECKPOINT_IMMEDIATE) &&
- !shutdown_requested &&
+ !ShutdownRequestPending &&
!ImmediateCheckpointRequested() &&
IsCheckpointOnSchedule(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)
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
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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;
+}
#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"
/*
* 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;
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);
* 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);
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)
* 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);
* command, and the second is to avoid conflicts with another
* archiver spawned by a newer postmaster.
*/
- if (got_SIGTERM || !PostmasterIsAlive())
+ if (ShutdownRequestPending || !PostmasterIsAlive())
return;
/*
#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"
*/
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.
#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);
* 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);
/*
* 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.
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
*
*/
#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"
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);
* --------------------------------
*/
-/*
- * 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)
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);
#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"
#define LOOPS_UNTIL_HIBERNATE 50
#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
*
* 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);
/* Clear any already-pending wakeups */
ResetLatch(MyLatch);
- HandleWalWriterInterrupts();
+ HandleMainLoopInterrupts();
/*
* Do what we're here for; then, if XLogBackgroundFlush() found useful
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;
-}
#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"
LogicalRepCtx->launcher_pid = MyProcPid;
/* Establish signal handlers. */
- pqsignal(SIGTERM, PostgresSigHupHandler);
+ pqsignal(SIGTERM, SignalHandlerForConfigReload);
pqsignal(SIGTERM, die);
BackgroundWorkerUnblockSignals();
#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"
logicalrep_worker_attach(worker_slot);
/* Setup signal handling */
- pqsignal(SIGHUP, PostgresSigHupHandler);
+ pqsignal(SIGHUP, SignalHandlerForConfigReload);
pqsignal(SIGTERM, die);
BackgroundWorkerUnblockSignals();
*/
#include "postgres.h"
-#include <signal.h>
#include <unistd.h>
#include "access/htup_details.h"
#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"
/* Signal handlers */
static void WalRcvSigHupHandler(SIGNAL_ARGS);
static void WalRcvShutdownHandler(SIGNAL_ARGS);
-static void WalRcvQuickDieHandler(SIGNAL_ARGS);
/*
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);
errno = save_errno;
}
-/*
- * 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.
*/
#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"
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 */
#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"
"invalid operation, such as division by zero.")));
}
-/*
- * 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()
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 */
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;
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;
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);
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * 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