Skip to content

Commit 6f1a407

Browse files
committed
Fix some more bugs in signal handlers and process shutdown logic.
WalSndKill was doing things exactly backwards: it should first clear MyWalSnd (to stop signal handlers from touching MyWalSnd->latch), then disown the latch, and only then mark the WalSnd struct unused by clearing its pid field. Also, WalRcvSigUsr1Handler and worker_spi_sighup failed to preserve errno, which is surely a requirement for any signal handler. Per discussion of recent buildfarm failures. Back-patch as far as the relevant code exists.
1 parent 27942ba commit 6f1a407

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

contrib/worker_spi/worker_spi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,19 @@ worker_spi_sigterm(SIGNAL_ARGS)
7979

8080
/*
8181
* Signal handler for SIGHUP
82-
* Set a flag to let the main loop to reread the config file, and set
82+
* Set a flag to tell the main loop to reread the config file, and set
8383
* our latch to wake it up.
8484
*/
8585
static void
8686
worker_spi_sighup(SIGNAL_ARGS)
8787
{
88+
int save_errno = errno;
89+
8890
got_sighup = true;
8991
if (MyProc)
9092
SetLatch(&MyProc->procLatch);
93+
94+
errno = save_errno;
9195
}
9296

9397
/*

src/backend/replication/walreceiver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,11 @@ WalRcvSigHupHandler(SIGNAL_ARGS)
737737
static void
738738
WalRcvSigUsr1Handler(SIGNAL_ARGS)
739739
{
740+
int save_errno = errno;
741+
740742
latch_sigusr1_handler();
743+
744+
errno = save_errno;
741745
}
742746

743747
/* SIGTERM: set flag for main loop, or shutdown immediately if safe */

src/backend/replication/walsender.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,17 +1214,23 @@ InitWalSenderSlot(void)
12141214
static void
12151215
WalSndKill(int code, Datum arg)
12161216
{
1217-
Assert(MyWalSnd != NULL);
1217+
WalSnd *walsnd = MyWalSnd;
1218+
1219+
Assert(walsnd != NULL);
1220+
1221+
/*
1222+
* Clear MyWalSnd first; then disown the latch. This is so that signal
1223+
* handlers won't try to touch the latch after it's no longer ours.
1224+
*/
1225+
MyWalSnd = NULL;
1226+
1227+
DisownLatch(&walsnd->latch);
12181228

12191229
/*
12201230
* Mark WalSnd struct no longer in use. Assume that no lock is required
12211231
* for this.
12221232
*/
1223-
MyWalSnd->pid = 0;
1224-
DisownLatch(&MyWalSnd->latch);
1225-
1226-
/* WalSnd struct isn't mine anymore */
1227-
MyWalSnd = NULL;
1233+
walsnd->pid = 0;
12281234
}
12291235

12301236
/*

0 commit comments

Comments
 (0)