Commit 214c7a4f authored by Tom Lane's avatar Tom Lane

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.
parent 7e1531a4
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "tcop/utility.h" #include "tcop/utility.h"
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(worker_spi_launch); PG_FUNCTION_INFO_V1(worker_spi_launch);
void _PG_init(void); void _PG_init(void);
...@@ -82,15 +83,19 @@ worker_spi_sigterm(SIGNAL_ARGS) ...@@ -82,15 +83,19 @@ worker_spi_sigterm(SIGNAL_ARGS)
/* /*
* Signal handler for SIGHUP * Signal handler for SIGHUP
* Set a flag to let the main loop to reread the config file, and set * Set a flag to tell the main loop to reread the config file, and set
* our latch to wake it up. * our latch to wake it up.
*/ */
static void static void
worker_spi_sighup(SIGNAL_ARGS) worker_spi_sighup(SIGNAL_ARGS)
{ {
int save_errno = errno;
got_sighup = true; got_sighup = true;
if (MyProc) if (MyProc)
SetLatch(&MyProc->procLatch); SetLatch(&MyProc->procLatch);
errno = save_errno;
} }
/* /*
......
...@@ -740,7 +740,11 @@ WalRcvSigHupHandler(SIGNAL_ARGS) ...@@ -740,7 +740,11 @@ WalRcvSigHupHandler(SIGNAL_ARGS)
static void static void
WalRcvSigUsr1Handler(SIGNAL_ARGS) WalRcvSigUsr1Handler(SIGNAL_ARGS)
{ {
int save_errno = errno;
latch_sigusr1_handler(); latch_sigusr1_handler();
errno = save_errno;
} }
/* SIGTERM: set flag for main loop, or shutdown immediately if safe */ /* SIGTERM: set flag for main loop, or shutdown immediately if safe */
......
...@@ -1401,17 +1401,23 @@ InitWalSenderSlot(void) ...@@ -1401,17 +1401,23 @@ InitWalSenderSlot(void)
static void static void
WalSndKill(int code, Datum arg) WalSndKill(int code, Datum arg)
{ {
Assert(MyWalSnd != NULL); WalSnd *walsnd = MyWalSnd;
Assert(walsnd != NULL);
/*
* Clear MyWalSnd first; then disown the latch. This is so that signal
* handlers won't try to touch the latch after it's no longer ours.
*/
MyWalSnd = NULL;
DisownLatch(&walsnd->latch);
/* /*
* Mark WalSnd struct no longer in use. Assume that no lock is required * Mark WalSnd struct no longer in use. Assume that no lock is required
* for this. * for this.
*/ */
MyWalSnd->pid = 0; walsnd->pid = 0;
DisownLatch(&MyWalSnd->latch);
/* WalSnd struct isn't mine anymore */
MyWalSnd = NULL;
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment