diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 0cd91c544fb..615a7f167dd 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -4272,7 +4272,14 @@ int PQflush(PGconn *conn); After sending any command or data on a nonblocking connection, call PQflush. 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 + PQflush again. If it becomes read-ready, call + PQconsumeInput, then call + PQflush again. Repeat until + PQflush returns 0. (It is necessary to check for + read-ready and drain the input with PQconsumeInput, + 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 PQflush returns 0, wait for the socket to be read-ready and then read the response as described above. diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index 05655c70645..8b0d8ef2bc6 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -908,16 +908,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 @@ -928,12 +918,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;