You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Eric Covener <co...@gmail.com> on 2015/06/19 15:51:29 UTC

option to block async write completion?

I have a proprietary module that uses a proprietary library. The
library needs an EOR cleanup that must run on the same thread as the
handler.  During async write completion it will often happen on the
wrong thread.

There's already a path for forcing a blocking write of a particular
bucket, so it is a one-liner to add a new condition.  But I am having
trouble deciding how to best flip this on -- add a new request_rec
field? Use a request note? Some kind of other way for a module to
influence the core output filter directly?

This is the neighborhood in core_filters.c:

511         if (APR_BUCKET_IS_FLUSH(bucket)
512             || non_file_bytes_in_brigade >= THRESHOLD_MAX_BUFFER
513             || morphing_bucket_in_brigade
514             || eor_buckets_in_brigade > MAX_REQUESTS_IN_PIPELINE) {
515             /* this segment of the brigade MUST be sent before returning. */
516
517             if (loglevel >= APLOG_TRACE6) {
518                 char *reason = APR_BUCKET_IS_FLUSH(bucket) ?
519                                "FLUSH bucket" :
520                                (non_file_bytes_in_brigade >=
THRESHOLD_MAX_BUFFER) ?

Thanks for any ideas.   I would default to adding a request_rec field,
but we have been bitten by just extending request_rec and that is not
really addressed yet so I am hesitant.  I don't know how expensive a
note lookup is, but it seems bad to do anything un-necesary per-bucet.

Re: option to block async write completion?

Posted by Eric Covener <co...@gmail.com>.
On Fri, Jun 19, 2015 at 9:54 AM, Jeff Trawick <tr...@gmail.com> wrote:
> Can ap_hook_{suspend_resume}_connection() allow you to remove that
> requirement?

I don't think so -- at least not easily.  It's effectively fopen() and
close() for a special kind of file (that's being served)

Re: option to block async write completion?

Posted by Jeff Trawick <tr...@gmail.com>.
On 06/19/2015 09:54 AM, Jeff Trawick wrote:
> On 06/19/2015 09:51 AM, Eric Covener wrote:
>> I have a proprietary module that uses a proprietary library. The
>> library needs an EOR cleanup that must run on the same thread as the
>> handler.  During async write completion it will often happen on the
>> wrong thread.
>
> Can ap_hook_{suspend_resume}_connection() allow you to remove that 
> requirement?
"{suspend|resume}"


Re: option to block async write completion?

Posted by Jeff Trawick <tr...@gmail.com>.
On 06/19/2015 09:51 AM, Eric Covener wrote:
> I have a proprietary module that uses a proprietary library. The
> library needs an EOR cleanup that must run on the same thread as the
> handler.  During async write completion it will often happen on the
> wrong thread.

Can ap_hook_{suspend_resume}_connection() allow you to remove that 
requirement?

>
> There's already a path for forcing a blocking write of a particular
> bucket, so it is a one-liner to add a new condition.  But I am having
> trouble deciding how to best flip this on -- add a new request_rec
> field? Use a request note? Some kind of other way for a module to
> influence the core output filter directly?
>
> This is the neighborhood in core_filters.c:
>
> 511         if (APR_BUCKET_IS_FLUSH(bucket)
> 512             || non_file_bytes_in_brigade >= THRESHOLD_MAX_BUFFER
> 513             || morphing_bucket_in_brigade
> 514             || eor_buckets_in_brigade > MAX_REQUESTS_IN_PIPELINE) {
> 515             /* this segment of the brigade MUST be sent before returning. */
> 516
> 517             if (loglevel >= APLOG_TRACE6) {
> 518                 char *reason = APR_BUCKET_IS_FLUSH(bucket) ?
> 519                                "FLUSH bucket" :
> 520                                (non_file_bytes_in_brigade >=
> THRESHOLD_MAX_BUFFER) ?
>
> Thanks for any ideas.   I would default to adding a request_rec field,
> but we have been bitten by just extending request_rec and that is not
> really addressed yet so I am hesitant.  I don't know how expensive a
> note lookup is, but it seems bad to do anything un-necesary per-bucet.


Re: option to block async write completion?

Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, Jun 30, 2015 at 8:53 PM, Plüm, Rüdiger, Vodafone Group
<ru...@vodafone.com> wrote:
>
>
>> -----Ursprüngliche Nachricht-----
>> Von: Eric Covener [mailto:covener@gmail.com]
>> Gesendet: Dienstag, 30. Juni 2015 20:09
>> An: Apache HTTP Server Development List
>> Betreff: Re: option to block async write completion?
>>
>> On Fri, Jun 19, 2015 at 10:03 AM, Eric Covener <co...@gmail.com>
>> wrote:
>> >> Maybe make MAX_REQUESTS_IN_PIPELINE configurable and use 1 in your
>> case?
>> >
>> > that's interesting, will check it out.
>>
>> This turned into a bot of a pain when I realized just using a flush
>> bucket accomplishes the same thing (everything up to the flush bucket
>> is blocking)
>
> Are you sure that works with every filter in between? As far as I remember some filters (mod_deflate?) just drop everything once they have seen EOS / EOR.

At least ap_http_filter() does...

Re: option to block async write completion?

Posted by Eric Covener <co...@gmail.com>.
On Tue, Jun 30, 2015 at 5:29 PM, Graham Leggett <mi...@sharp.fm> wrote:
> To be 100% safe, send the flush bucket down the stack on it’s own, not tacked onto the end of the brigade with the EOS.

Thanks all -- I lucked into having that relationship already between
the heap buckets and EOS, and the flushes are just tacked on when the
heap buckets are passed.

Re: option to block async write completion?

Posted by Graham Leggett <mi...@sharp.fm>.
On 30 Jun 2015, at 8:53 PM, Plüm, Rüdiger, Vodafone Group <ru...@vodafone.com> wrote:

>> This turned into a bot of a pain when I realized just using a flush
>> bucket accomplishes the same thing (everything up to the flush bucket
>> is blocking)
> 
> Are you sure that works with every filter in between? As far as I remember some filters (mod_deflate?) just drop everything once they have seen EOS / EOR.

mod_deflate is a per-request filter, the request ceases to exist after EOS/EOR, so in theory this wouldn’t affect the flush bucket.

To be 100% safe, send the flush bucket down the stack on it’s own, not tacked onto the end of the brigade with the EOS.

Regards,
Graham
—


AW: option to block async write completion?

Posted by Plüm, Rüdiger, Vodafone Group <ru...@vodafone.com>.

> -----Ursprüngliche Nachricht-----
> Von: Eric Covener [mailto:covener@gmail.com]
> Gesendet: Dienstag, 30. Juni 2015 20:09
> An: Apache HTTP Server Development List
> Betreff: Re: option to block async write completion?
> 
> On Fri, Jun 19, 2015 at 10:03 AM, Eric Covener <co...@gmail.com>
> wrote:
> >> Maybe make MAX_REQUESTS_IN_PIPELINE configurable and use 1 in your
> case?
> >
> > that's interesting, will check it out.
> 
> This turned into a bot of a pain when I realized just using a flush
> bucket accomplishes the same thing (everything up to the flush bucket
> is blocking)

Are you sure that works with every filter in between? As far as I remember some filters (mod_deflate?) just drop everything once they have seen EOS / EOR.

Regards

Rüdiger

Re: option to block async write completion?

Posted by Eric Covener <co...@gmail.com>.
On Fri, Jun 19, 2015 at 10:03 AM, Eric Covener <co...@gmail.com> wrote:
>> Maybe make MAX_REQUESTS_IN_PIPELINE configurable and use 1 in your case?
>
> that's interesting, will check it out.

This turned into a bot of a pain when I realized just using a flush
bucket accomplishes the same thing (everything up to the flush bucket
is blocking)

Re: option to block async write completion?

Posted by Eric Covener <co...@gmail.com>.
On Fri, Jun 19, 2015 at 10:02 AM, Yann Ylavic <yl...@gmail.com> wrote:
> Maybe make MAX_REQUESTS_IN_PIPELINE configurable and use 1 in your case?

that's interesting, will check it out.

Re: option to block async write completion?

Posted by Yann Ylavic <yl...@gmail.com>.
On Fri, Jun 19, 2015 at 3:51 PM, Eric Covener <co...@gmail.com> wrote:
>
> Thanks for any ideas.

Maybe make MAX_REQUESTS_IN_PIPELINE configurable and use 1 in your case?