diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-02-01 16:20:56 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-02-01 16:21:23 -0500 |
commit | 214c7a4f0b1784ce855512c2961b09c9f51dafd8 (patch) | |
tree | 4eb56ad918fddf0a219e620156916875044a5c00 /src | |
parent | 7e1531a4504248d9df5deae8c4aa9340adaa7ef5 (diff) | |
download | postgresql-214c7a4f0b1784ce855512c2961b09c9f51dafd8.tar.gz postgresql-214c7a4f0b1784ce855512c2961b09c9f51dafd8.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/replication/walreceiver.c | 4 | ||||
-rw-r--r-- | src/backend/replication/walsender.c | 18 |
2 files changed, 16 insertions, 6 deletions
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index cc3d7753074..e31977eee02 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -740,7 +740,11 @@ WalRcvSigHupHandler(SIGNAL_ARGS) static void WalRcvSigUsr1Handler(SIGNAL_ARGS) { + int save_errno = errno; + latch_sigusr1_handler(); + + errno = save_errno; } /* SIGTERM: set flag for main loop, or shutdown immediately if safe */ diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 119a920af21..a661d882771 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1401,17 +1401,23 @@ InitWalSenderSlot(void) static void 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 * for this. */ - MyWalSnd->pid = 0; - DisownLatch(&MyWalSnd->latch); - - /* WalSnd struct isn't mine anymore */ - MyWalSnd = NULL; + walsnd->pid = 0; } /* |