aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-02-01 16:21:07 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-02-01 16:21:38 -0500
commit03f06ff383eaeb80e1ad1f2aa496ab0cb283f3da (patch)
treeff3b88b02f2c581de8fb8a53ee15e4b1da3ce2df /src
parente5c22c15d863fc557b9510cc5865c23803766b04 (diff)
downloadpostgresql-03f06ff383eaeb80e1ad1f2aa496ab0cb283f3da.tar.gz
postgresql-03f06ff383eaeb80e1ad1f2aa496ab0cb283f3da.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/walsender.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index bbde1c32e73..7b44f9b0443 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -920,17 +920,23 @@ InitWalSnd(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;
}
/*