aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/libpq.sgml9
-rw-r--r--src/interfaces/libpq/fe-misc.c27
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;