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.
This commit is contained in:
parent
7e1531a450
commit
214c7a4f0b
@ -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)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user