• Tom Lane's avatar
    Use pselect(2) not select(2), if available, to wait in postmaster's loop. · 81069a9e
    Tom Lane authored
    Traditionally we've unblocked signals, called select(2), and then blocked
    signals again.  The code expects that the select() will be cancelled with
    EINTR if an interrupt occurs; but there's a race condition, which is that
    an already-pending signal will be delivered as soon as we unblock, and then
    when we reach select() there will be nothing preventing it from waiting.
    This can result in a long delay before we perform any action that
    ServerLoop was supposed to have taken in response to the signal.  As with
    the somewhat-similar symptoms fixed by commit 89390208, the main practical
    problem is slow launching of parallel workers.  The window for trouble is
    usually pretty short, corresponding to one iteration of ServerLoop; but
    it's not negligible.
    
    To fix, use pselect(2) in place of select(2) where available, as that's
    designed to solve exactly this problem.  Where not available, we continue
    to use the old way, and are no worse off than before.
    
    pselect(2) has been required by POSIX since about 2001, so most modern
    platforms should have it.  A bigger portability issue is that some
    implementations are said to be non-atomic, ie pselect() isn't really
    any different from unblock/select/reblock.  Still, we're no worse off
    than before on such a platform.
    
    There is talk of rewriting the postmaster to use a WaitEventSet and
    not do signal response work in signal handlers, at which point this
    could be reverted, since we'd be using a self-pipe to solve the race
    condition.  But that's not happening before v11 at the earliest.
    
    Back-patch to 9.6.  The problem exists much further back, but the
    worst symptom arises only in connection with parallel query, so it
    does not seem worth taking any portability risks in older branches.
    
    Discussion: https://postgr.es/m/9205.1492833041@sss.pgh.pa.us
    81069a9e
postmaster.c 176 KB