[snip] (wrowe's exposition of a possible non-blocking filter chain implementation)
Your poll bucket idea would be welcome for input, although it would only save a bit of work since we already have APR_NONBLOCK_READ apr_bucket_read(b, &bdata, &blen, APR_NONBLOCK_READ); For polling output, I had the idea of an ap_pass_brigade_nb() for a non-blocking brigade pass. The return value would indicate success, failure, or blocking. (Or modify passing brigade to take a flag like APR_NONBLOCK_WRITE or APR_BLOCK_WRITE) When I first looked at the brigade passing code, I mistakenly assumed that AP_NOBODY_WROTE was for. My current understanding of AP_NOBODY_WROTE is that it should be an ap_assert() fatal error because the filter chain went off into thin air, and so did the brigade that was passed to it. Anyway, ap_pass_brigade_nb() would require that filters learn an extra return value, and that they check the return value from ap_pass_brigade_nb(). That might be too much to ask. Currently, I'm playing with finding the connection socket by searching the output filters for f->frec->name as "core" and then stealing the connection socket from ((core_net_rec)f->ctx)->client_socket. Polling on that will reveal if the network connection is blocking. Until then, I can send data. If it is blocking, I assume that I should stop reading data (e.g. CGI output) until it clears. This theoretically works for all output, even if there is an intermediate output filter that is buffering all my data (mod_deflate or similar). I'd be very happy if there was a sanctioned routine which I could call to get a poll descriptor to use to determine if output would block. This would allow the returned descriptor to be inserted anywhere in the filter chain by more knowledgable filters downstream (e.g. if we're a subrequest that is reverse-proxied that is mod_ext_filter that is...) instead of me just pulling the socket all the way at the end. Cheers, Glenn
