diff options
-rw-r--r-- | doc/src/sgml/libpq.sgml | 9 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-misc.c | 27 |
2 files changed, 25 insertions, 11 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index d0fbd487f12..54dd71e03bf 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -4380,7 +4380,14 @@ int PQflush(PGconn *conn); <para> After sending any command or data on a nonblocking connection, call <function>PQflush</function>. If it returns 1, wait for the socket - to be write-ready and call it again; repeat until it returns 0. Once + to become read- or write-ready. If it becomes write-ready, call + <function>PQflush</function> again. If it becomes read-ready, call + <function>PQconsumeInput</function>, then call + <function>PQflush</function> again. Repeat until + <function>PQflush</function> returns 0. (It is necessary to check for + read-ready and drain the input with <function>PQconsumeInput</function>, + because the server can block trying to send us data, e.g. NOTICE + messages, and won't read our data until we read its.) Once <function>PQflush</function> returns 0, wait for the socket to be read-ready and then read the response as described above. </para> diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 1d5959b9ed3..488841e1e6b 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -904,16 +904,6 @@ pqSendSome(PGconn *conn, int len) /* * We didn't send it all, wait till we can send more. * - * If the connection is in non-blocking mode we don't wait, but - * return 1 to indicate that data is still pending. - */ - if (pqIsnonblocking(conn)) - { - result = 1; - break; - } - - /* * There are scenarios in which we can't send data because the * communications channel is full, but we cannot expect the server * to clear the channel eventually because it's blocked trying to @@ -924,12 +914,29 @@ pqSendSome(PGconn *conn, int len) * again. Furthermore, it is possible that such incoming data * might not arrive until after we've gone to sleep. Therefore, * we wait for either read ready or write ready. + * + * In non-blocking mode, we don't wait here directly, but return + * 1 to indicate that data is still pending. The caller should + * wait for both read and write ready conditions, and call + * PQconsumeInput() on read ready, but just in case it doesn't, we + * call pqReadData() ourselves before returning. That's not + * enough if the data has not arrived yet, but it's the best we + * can do, and works pretty well in practice. (The documentation + * used to say that you only need to wait for write-ready, so + * there are still plenty of applications like that out there.) */ if (pqReadData(conn) < 0) { result = -1; /* error message already set up */ break; } + + if (pqIsnonblocking(conn)) + { + result = 1; + break; + } + if (pqWait(TRUE, TRUE, conn)) { result = -1; |