postgres.git / summary / log / commit / refs

commit    81b116d987a779de7c97f5fd415a7c8348b9afff
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Sat Feb 01 21:21:04 2014 +0000
First released in: 9.4.0, 9.1.12, 9.2.7, 9.3.3

    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.


src/backend/replication/walsender.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index bd64c2873f7..fdf44a46e5f 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -950,17 +950,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; } /* [parent: fad443753eea]