On Thu, Feb 4, 2016 at 11:53 PM, Joachim Achtzehnter <joac...@kraut.ca> wrote: > 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:
We don't want to select/poll here (timeout is 0), we want to directly read non-blocking on the socket. Since apr_socket_timeout_set(sock, 0)::sononblock() is called (and succeeds!), recv() should never block (or the system is flawed, or the socket is in some inconsistent state). If the timeout were <0, we'd want recv() to block (directly still) and hence need soblock() before. If timeout >0, we don't want to wait more than that timeout, so we use select/poll (timed wait). > > How about this small patch: No, we don't want to poll() before recv() in non-blocking mode, one system call is enough. > > This seems to get it working, You mean poll()+recv() succeeds? or fails: at poll(), at recv()? immediatly in any case? I'm puzzled, why direct non-blocking recv() would block (or not fail)? Are you sure the earlier sononblock() call succeeded (ie. my patch on socket_bucket_read() does not help)? Anyway, I think we need an strace of the process for the whole connection to figure out the successive syscalls on the socket.