<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>
/*
* 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
* 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;