postgres.git / summary / log / commit / refs

commit    ee6c5f10d53f9dd73007535ff4cba752e7e70f5e
Author:   Andres Freund <andres@anarazel.de>
Date:     Tue Jun 03 12:02:54 2014 +0000
First released in: 9.4.0, 9.1.14, 9.2.9, 9.3.5

    Set the process latch when processing recovery conflict interrupts.
    
    Because RecoveryConflictInterrupt() didn't set the process latch
    anything using the latter to wait for events didn't get notified about
    recovery conflicts. Most latch users are never the target of recovery
    conflicts, which explains the lack of reports about this until
    now.
    Since 9.3 two possible affected users exist though: The sql callable
    pg_sleep() now uses latches to wait and background workers are
    expected to use latches in their main loop. Both would currently wait
    until the end of WaitLatch's timeout.
    
    Fix by adding a SetLatch() to RecoveryConflictInterrupt(). It'd also
    be possible to fix the issue by having each latch user set
    set_latch_on_sigusr1. That seems failure prone and though, as most of
    these callsites won't often receive recovery conflicts and thus will
    likely only be tested against normal query cancels et al. It'd also be
    unnecessarily verbose.
    
    Backpatch to 9.1 where latches were introduced. Arguably 9.3 would be
    sufficient, because that's where pg_sleep() was converted to waiting
    on the latch and background workers got introduced; but there could be
    user level code making use of the latch pre 9.3.


src/backend/tcop/postgres.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 737feb6f69f..6d4d8ac0339 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -2809,6 +2809,16 @@ RecoveryConflictInterrupt(ProcSignalReason reason) } } + /* + * Set the process latch. This function essentially emulates signal + * handlers like die() and StatementCancelHandler() and it seems prudent + * to behave similarly as they do. Alternatively all plain backend code + * waiting on that latch, expecting to get interrupted by query cancels et + * al., would also need to set set_latch_on_sigusr1. + */ + if (MyProc) + SetLatch(&MyProc->procLatch); + errno = save_errno; } [parent: c102c32e9ad3]