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 <[EMAIL PROTECTED]> Tuesday, July 16, 2002 12:24:24 AM >>> On Tue, Jul 16, 2002 at 05:50:40AM -0000, [EMAIL PROTECTED] 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
