• Heikki Linnakangas's avatar
    Fix potential deadlock with libpq non-blocking mode. · 2a3f6e36
    Heikki Linnakangas authored
    If libpq output buffer is full, pqSendSome() function tries to drain any
    incoming data. This avoids deadlock, if the server e.g. sends a lot of
    NOTICE messages, and blocks until we read them. However, pqSendSome() only
    did that in blocking mode. In non-blocking mode, the deadlock could still
    happen.
    
    To fix, take a two-pronged approach:
    
    1. Change the documentation to instruct that when PQflush() returns 1, you
    should wait for both read- and write-ready, and call PQconsumeInput() if it
    becomes read-ready. That fixes the deadlock, but applications are not going
    to change overnight.
    
    2. In pqSendSome(), drain the input buffer before returning 1. This
    alleviates the problem for applications that only wait for write-ready. In
    particular, a slow but steady stream of NOTICE messages during COPY FROM
    STDIN will no longer cause a deadlock. The risk remains that the server
    attempts to send a large burst of data and fills its output buffer, and at
    the same time the client also sends enough data to fill its output buffer.
    The application will deadlock if it goes to sleep, waiting for the socket
    to become write-ready, before the server's data arrives. In practice,
    NOTICE messages and such that the server might be sending are usually
    short, so it's highly unlikely that the server would fill its output buffer
    so quickly.
    
    Backpatch to all supported versions.
    2a3f6e36
libpq.sgml 289 KB