Skip to content

Commit 7dbfea3

Browse files
committed
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
1 parent 1e53fe0 commit 7dbfea3

File tree

18 files changed

+191
-399
lines changed

18 files changed

+191
-399
lines changed

src/backend/postmaster/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ OBJS = \
1818
bgwriter.o \
1919
checkpointer.o \
2020
fork_process.o \
21+
interrupt.o \
2122
pgarch.o \
2223
pgstat.o \
2324
postmaster.o \

src/backend/postmaster/autovacuum.c

+8-21
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#include "pgstat.h"
8585
#include "postmaster/autovacuum.h"
8686
#include "postmaster/fork_process.h"
87+
#include "postmaster/interrupt.h"
8788
#include "postmaster/postmaster.h"
8889
#include "storage/bufmgr.h"
8990
#include "storage/ipc.h"
@@ -139,7 +140,6 @@ static bool am_autovacuum_worker = false;
139140

140141
/* Flags set by signal handlers */
141142
static volatile sig_atomic_t got_SIGUSR2 = false;
142-
static volatile sig_atomic_t got_SIGTERM = false;
143143

144144
/* Comparison points for determining whether freeze_max_age is exceeded */
145145
static TransactionId recentXid;
@@ -344,7 +344,6 @@ static void autovac_report_activity(autovac_table *tab);
344344
static void autovac_report_workitem(AutoVacuumWorkItem *workitem,
345345
const char *nspname, const char *relname);
346346
static void avl_sigusr2_handler(SIGNAL_ARGS);
347-
static void avl_sigterm_handler(SIGNAL_ARGS);
348347
static void autovac_refresh_stats(void);
349348

350349

@@ -450,9 +449,9 @@ AutoVacLauncherMain(int argc, char *argv[])
450449
* backend, so we use the same signal handling. See equivalent code in
451450
* tcop/postgres.c.
452451
*/
453-
pqsignal(SIGHUP, PostgresSigHupHandler);
452+
pqsignal(SIGHUP, SignalHandlerForConfigReload);
454453
pqsignal(SIGINT, StatementCancelHandler);
455-
pqsignal(SIGTERM, avl_sigterm_handler);
454+
pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
456455

457456
pqsignal(SIGQUIT, quickdie);
458457
InitializeTimeouts(); /* establishes SIGALRM handler */
@@ -553,7 +552,7 @@ AutoVacLauncherMain(int argc, char *argv[])
553552
RESUME_INTERRUPTS();
554553

555554
/* if in shutdown mode, no need for anything further; just go away */
556-
if (got_SIGTERM)
555+
if (ShutdownRequestPending)
557556
AutoVacLauncherShutdown();
558557

559558
/*
@@ -605,7 +604,7 @@ AutoVacLauncherMain(int argc, char *argv[])
605604
*/
606605
if (!AutoVacuumingActive())
607606
{
608-
if (!got_SIGTERM)
607+
if (!ShutdownRequestPending)
609608
do_start_worker();
610609
proc_exit(0); /* done */
611610
}
@@ -622,7 +621,7 @@ AutoVacLauncherMain(int argc, char *argv[])
622621
rebuild_database_list(InvalidOid);
623622

624623
/* loop until shutdown request */
625-
while (!got_SIGTERM)
624+
while (!ShutdownRequestPending)
626625
{
627626
struct timeval nap;
628627
TimestampTz current_time = 0;
@@ -800,7 +799,7 @@ static void
800799
HandleAutoVacLauncherInterrupts(void)
801800
{
802801
/* the normal shutdown case */
803-
if (got_SIGTERM)
802+
if (ShutdownRequestPending)
804803
AutoVacLauncherShutdown();
805804

806805
if (ConfigReloadPending)
@@ -1415,18 +1414,6 @@ avl_sigusr2_handler(SIGNAL_ARGS)
14151414
errno = save_errno;
14161415
}
14171416

1418-
/* SIGTERM: time to die */
1419-
static void
1420-
avl_sigterm_handler(SIGNAL_ARGS)
1421-
{
1422-
int save_errno = errno;
1423-
1424-
got_SIGTERM = true;
1425-
SetLatch(MyLatch);
1426-
1427-
errno = save_errno;
1428-
}
1429-
14301417

14311418
/********************************************************************
14321419
* AUTOVACUUM WORKER CODE
@@ -1525,7 +1512,7 @@ AutoVacWorkerMain(int argc, char *argv[])
15251512
* backend, so we use the same signal handling. See equivalent code in
15261513
* tcop/postgres.c.
15271514
*/
1528-
pqsignal(SIGHUP, PostgresSigHupHandler);
1515+
pqsignal(SIGHUP, SignalHandlerForConfigReload);
15291516

15301517
/*
15311518
* SIGINT is used to signal canceling the current table's vacuum; SIGTERM

src/backend/postmaster/bgworker.c

+2-23
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212

1313
#include "postgres.h"
1414

15-
#include <unistd.h>
16-
1715
#include "access/parallel.h"
1816
#include "libpq/pqsignal.h"
1917
#include "miscadmin.h"
2018
#include "pgstat.h"
2119
#include "port/atomics.h"
2220
#include "postmaster/bgworker_internals.h"
21+
#include "postmaster/interrupt.h"
2322
#include "postmaster/postmaster.h"
2423
#include "replication/logicallauncher.h"
2524
#include "replication/logicalworker.h"
@@ -641,26 +640,6 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
641640
return true;
642641
}
643642

644-
static void
645-
bgworker_quickdie(SIGNAL_ARGS)
646-
{
647-
/*
648-
* We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
649-
* because shared memory may be corrupted, so we don't want to try to
650-
* clean up our transaction. Just nail the windows shut and get out of
651-
* town. The callbacks wouldn't be safe to run from a signal handler,
652-
* anyway.
653-
*
654-
* Note we do _exit(2) not _exit(0). This is to force the postmaster into
655-
* a system reset cycle if someone sends a manual SIGQUIT to a random
656-
* backend. This is necessary precisely because we don't clean up our
657-
* shared memory state. (The "dead man switch" mechanism in pmsignal.c
658-
* should ensure the postmaster sees this as a crash, too, but no harm in
659-
* being doubly sure.)
660-
*/
661-
_exit(2);
662-
}
663-
664643
/*
665644
* Standard SIGTERM handler for background workers
666645
*/
@@ -754,7 +733,7 @@ StartBackgroundWorker(void)
754733
pqsignal(SIGTERM, bgworker_die);
755734
pqsignal(SIGHUP, SIG_IGN);
756735

757-
pqsignal(SIGQUIT, bgworker_quickdie);
736+
pqsignal(SIGQUIT, SignalHandlerForCrashExit);
758737
InitializeTimeouts(); /* establishes SIGALRM handler */
759738

760739
pqsignal(SIGPIPE, SIG_IGN);

src/backend/postmaster/bgwriter.c

+5-88
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,13 @@
3434
*/
3535
#include "postgres.h"
3636

37-
#include <signal.h>
38-
#include <sys/time.h>
39-
#include <unistd.h>
40-
4137
#include "access/xlog.h"
4238
#include "access/xlog_internal.h"
4339
#include "libpq/pqsignal.h"
4440
#include "miscadmin.h"
4541
#include "pgstat.h"
4642
#include "postmaster/bgwriter.h"
43+
#include "postmaster/interrupt.h"
4744
#include "storage/buf_internals.h"
4845
#include "storage/bufmgr.h"
4946
#include "storage/condition_variable.h"
@@ -86,18 +83,6 @@ int BgWriterDelay = 200;
8683
static TimestampTz last_snapshot_ts;
8784
static XLogRecPtr last_snapshot_lsn = InvalidXLogRecPtr;
8885

89-
/*
90-
* Flags set by interrupt handlers for later service in the main loop.
91-
*/
92-
static volatile sig_atomic_t shutdown_requested = false;
93-
94-
static void HandleBackgroundWriterInterrupts(void);
95-
96-
/* Signal handlers */
97-
98-
static void bg_quickdie(SIGNAL_ARGS);
99-
static void ReqShutdownHandler(SIGNAL_ARGS);
100-
10186

10287
/*
10388
* Main entry point for bgwriter process
@@ -116,10 +101,10 @@ BackgroundWriterMain(void)
116101
/*
117102
* Properly accept or ignore signals that might be sent to us.
118103
*/
119-
pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */
104+
pqsignal(SIGHUP, SignalHandlerForConfigReload);
120105
pqsignal(SIGINT, SIG_IGN);
121-
pqsignal(SIGTERM, ReqShutdownHandler); /* shutdown */
122-
pqsignal(SIGQUIT, bg_quickdie); /* hard crash time */
106+
pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
107+
pqsignal(SIGQUIT, SignalHandlerForCrashExit);
123108
pqsignal(SIGALRM, SIG_IGN);
124109
pqsignal(SIGPIPE, SIG_IGN);
125110
pqsignal(SIGUSR1, procsignal_sigusr1_handler);
@@ -241,7 +226,7 @@ BackgroundWriterMain(void)
241226
/* Clear any already-pending wakeups */
242227
ResetLatch(MyLatch);
243228

244-
HandleBackgroundWriterInterrupts();
229+
HandleMainLoopInterrupts();
245230

246231
/*
247232
* Do one cycle of dirty-buffer writing.
@@ -354,71 +339,3 @@ BackgroundWriterMain(void)
354339
prev_hibernate = can_hibernate;
355340
}
356341
}
357-
358-
/*
359-
* Process any new interrupts.
360-
*/
361-
static void
362-
HandleBackgroundWriterInterrupts(void)
363-
{
364-
if (ConfigReloadPending)
365-
{
366-
ConfigReloadPending = false;
367-
ProcessConfigFile(PGC_SIGHUP);
368-
}
369-
370-
if (shutdown_requested)
371-
{
372-
/*
373-
* From here on, elog(ERROR) should end with exit(1), not send
374-
* control back to the sigsetjmp block above
375-
*/
376-
ExitOnAnyError = true;
377-
/* Normal exit from the bgwriter is here */
378-
proc_exit(0); /* done */
379-
}
380-
}
381-
382-
383-
/* --------------------------------
384-
* signal handler routines
385-
* --------------------------------
386-
*/
387-
388-
/*
389-
* bg_quickdie() occurs when signalled SIGQUIT by the postmaster.
390-
*
391-
* Some backend has bought the farm,
392-
* so we need to stop what we're doing and exit.
393-
*/
394-
static void
395-
bg_quickdie(SIGNAL_ARGS)
396-
{
397-
/*
398-
* We DO NOT want to run proc_exit() or atexit() callbacks -- we're here
399-
* because shared memory may be corrupted, so we don't want to try to
400-
* clean up our transaction. Just nail the windows shut and get out of
401-
* town. The callbacks wouldn't be safe to run from a signal handler,
402-
* anyway.
403-
*
404-
* Note we do _exit(2) not _exit(0). This is to force the postmaster into
405-
* a system reset cycle if someone sends a manual SIGQUIT to a random
406-
* backend. This is necessary precisely because we don't clean up our
407-
* shared memory state. (The "dead man switch" mechanism in pmsignal.c
408-
* should ensure the postmaster sees this as a crash, too, but no harm in
409-
* being doubly sure.)
410-
*/
411-
_exit(2);
412-
}
413-
414-
/* SIGTERM: set flag to shutdown and exit */
415-
static void
416-
ReqShutdownHandler(SIGNAL_ARGS)
417-
{
418-
int save_errno = errno;
419-
420-
shutdown_requested = true;
421-
SetLatch(MyLatch);
422-
423-
errno = save_errno;
424-
}

0 commit comments

Comments
 (0)