You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Bill Stoddard <bi...@wstoddard.com> on 2002/07/16 18:56:54 UTC

RE: cvs commit: apr-util/buckets apr_buckets_pipe.capr_buckets_socket.c

Ignore me if this is noise, but I thought the c-l filter did the pipe reads,
not mod_cgi. In the c-l filter, we do the first pipe read non-blocking in
order to be given the opportunity to flush bytes in the filter stack to the
network.

Bill

>    The problem with the MOD_CGI case is that it *doesn't* call
> pipe_bucket_read() with APR_BLOCK_READ.  In fact it calls it with
> APR_NONBLOCK_READ which is what prompted the modification in the first
> place.  If your analysis as to the definitions of APR_BLOCK_READ vs
> APR_NONBLOCK_READ is correct, then let me dig a little deeper in the
> code to figure out exactly why MOD_CGI is ultimately passing an
> APR_NONBLOCK_READ (unless somebody else already knows).  What I do know
> is that if pipe_socket_read() is allowed to return with an EWOULDBLOCK
> error code, I end up with a browser response of "Premature end of
> script..."  when in fact the data is there, just not at the right time.
>
> Brad
>
> Brad Nicholes
> Senior Software Engineer
> Novell, Inc., the leading provider of Net business solutions
> http://www.novell.com
>
> >>> Justin Erenkrantz <je...@apache.org> Tuesday, July 16, 2002
> 12:24:24 AM >>>
> On Tue, Jul 16, 2002 at 05:50:40AM -0000, jerenkrantz@apache.org
> wrote:
> > jerenkrantz    2002/07/15 22:50:40
> >
> >   Modified:    buckets  apr_buckets_pipe.c apr_buckets_socket.c
> >   Log:
> >   Revert rev 1.42 of apr_buckets_socket.c and rev 1.52 of
> apr_buckets_pipe.c
> >
> >   APR_NONBLOCK_READ means that we have no timeout - i.e. that we
> read
> >   immediately.  Leaving the timeout set by the 'upstream' application
> is
> >   incorrect in this state.
> >
> >   This fixes httpd-2.0 blocking in check_pipeline_flush() for EATCRLF
> modes.
>
> Brad's original commit had no chance of ever working as it made
> APR_NONBLOCK_READ block.  There was discussion before about this
> (and Cliff was right, IMHO), but the key concept missed was that
> APR_NONBLOCK_READ means an immediate read, not a timeout-based read.
>
> Let's sum up the APR socket timeouts and how they correspond to the
> APR_BLOCK_READ and APR_NONBLOCK_READ enums in apr-util.  This
> applies to sockets and pipes on Unix (no idea about Win32).
>
> When the APR socket timeout is < 0, we use a blocking socket.
> When the APR socket timeout is >=0, we use a non-blocking socket.
>
> When the timeout is >0 (hence non-blocking) and read() doesn't
> return any data, we call apr_wait_for_io_or_timeout() to wait for the
> timeout value.  So, the result is that if the timeout value is 0, we
> return immediately (one-shot non-blocking read).
>
> APR_BLOCK_READ indicates that the read should wait for the socket's
> *timeout* period for data.  It leaves the timeout values alone.  So,
> per the socket timeout rules above, if the timeout < 0, then it will
> wait indefinitely.  If the timeout is > 0, then we will wait for the
> timeout.  And, if the timeout is 0 and APR_BLOCK_READ is called, it
> essentially becomes APR_NONBLOCK_READ (see next).
>
> APR_NONBLOCK_READ indicates that the read() should return immediately
> in any case.  It should *never* block.  The timeouts don't apply.
>
> So, if your application was using APR_NONBLOCK_READ and expected it
> to wait for the timeout period, then it should have been using
> APR_BLOCK_READ.  Brad pointed out mod_cgi.c as his example case, but
> that uses APR_BLOCK_READ (per above, uses a non-blocking pipe with a
> timeout).  So, the timeout value that mod_cgi sets is respected.
>
> I hope this eliminates the confusion.  -- justin
>