On 2016-02-04 0:54, Yann Ylavic wrote:

On Thu, Feb 4, 2016 at 9:41 AM, Yann Ylavic <ylavic....@gmail.com> wrote:
Doesn't the socket_bucket_read() call (frame #3) enter
apr_socket_timeout_set(p, 0), and hence sononblock() which puts the
socket in O_NONBLOCK?

and resets APR_INCOMPLETE_READ.

Yes, it does:

    if (t <= 0) {
        sock->options &= ~APR_INCOMPLETE_READ;
    }

But isn't this precisely the problem? The socket_buffer_read() implementation in "srclib/apr/network_io/unix/sendrecv.c" uses select() only if the APR_INCOMPLETE_READ flag is SET:

    if (sock->options & APR_INCOMPLETE_READ) {
        sock->options &= ~APR_INCOMPLETE_READ;
        goto do_select;
    }

If this flag is clear it goes into the blocking read loop instead:

    do {
        rv = read(sock->socketdes, buf, (*len));
    } while (rv == -1 && errno == EINTR);

How about this small patch:

--- srclib/apr/network_io/unix/sockopt.c.orig 2012-11-07 08:10:09.000000000 -0800
+++ srclib/apr/network_io/unix/sockopt.c        2016-02-04 14:20:35.755530111 
-0800
@@ -102,7 +102,7 @@
     /* must disable the incomplete read support if we disable
      * a timeout
      */
-    if (t <= 0) {
+    if (t < 0) {
         sock->options &= ~APR_INCOMPLETE_READ;
     }
     sock->timeout = t;

This seems to get it working, but I'm not sure if there are other reasons, not related to blocking versus non-blocking behaviour, for the flag to get cleared when timeout is zero.

Thanks,

Joachim

--
joac...@kraut.ca http://www.kraut.ca

Reply via email to