[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

Reply via email to