httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <>
Subject Re: the ap_r* thing (was: Re: Apache 2.0 beta STATUS)
Date Mon, 22 Jan 2001 18:51:58 GMT
On Mon, Jan 22, 2001 at 01:16:23PM -0500, Greg Marr wrote:
> At 06:36 AM 01/22/2001, Greg Stein wrote:
> >An answer is to tell everybody "you must use r->bb, and never your 
> >own brigade."
> A better answer is to tell people to ap_rflush() before calling 
> functions they don't control that may generate output, and to call 
> ap_rflush after generating output using ap_r* if the function may be 
> called by functions they don't control.

This would be inadvisable. ap_rflush() will deliver to the network. The hope
is to synchronize the ordering, rather than generate network packets :-)

> >By using a filter in my patch, I've trapped all output to the 
> >network.  Nothing can go without passing through that 
> >filter.  Therefore, I have a perfect choke point to ensure that I 
> >can order all the output properly.
> Actually, all the output better be ordered properly before it gets to 
> your filter, since your filter can be pushed down the stack by 
> another filter inserting itself higher up.

Apache output is ordered by its entry to the output filter chain. There is
no other definition. It is that chain that transmits it onto the network, so
it must be correct on entry.

[ there may be no filters other than the core_output_filter ]

So, yes: your statement is correct. But it isn't anything new. :-)

> Is there ever the possibility of a filter being inserted into the 
> stack after the first ap_r* call?  If so, and that filter gets placed 
> before your filter, won't that totally hose any data currently in the 
> output filter's buffer?

That is a similar situation to the case where the ap_r* went to the network
before the new filter was inserted.

Basically: dynamic insertion of filters, while content is being generated,
is always a tricky business. The general rule of thumb is that a filter can
only insert another filter *after* itself. But even then, we make no
guarantees about whether that new filter has seen/processes all of the

So, again: nothing new here. :-)

> >My patch has *zero* requirements on module authors.  Use whatever 
> >API you have been using or want to use.  It doesn't matter, and you 
> >don't ever have to worry about what somebody else is using.  There 
> >is no possibility for synchronization problems.
> That's true, but it also has the possibility that the entire thing 
> can be turned off by a filter being inserted above it in the stack, 
> in which case Apache's back at its current performance.

Correct. We can always come up with a pathological case :-). Until somebody
goes and constructs a filter that specifically is intended to precede the
OLD_WRITE filter, then we're going to see all of the performance gains.
Someone has to specifically break it. If you truly believe this is a
possibility, then we can make an allowance within the AP_FTYPE constants for
more insurance. (personally, I don't see the situation arising, but am happy
to buy more insurance :-)

> >I'm all for creating an APR solution, but the number one priority is 
> >Apache.  If our solution also happens to work for APR, then 
> >great.  But I don't believe that we can necessarily say "this works 
> >for APR" and then wedge it into Apache and make module authors need 
> >to be aware of the various output mechanisms and compensate for 
> >potential ordering problems.
> It removes any possibility of output ordering problems, but also adds 
> a possibility of a filter ordering problem rendering it ineffective.

You need to work at it for that to happen :-). There are no filters that are
defined to precende AP_FTYPE_CONTENT. Again, we can make an allowance if
this is deemed a *true* risk. I'm +0 for an AP_FTYPE change to clarify.

> >*) ap_rwrite(my_buffer, 100000, r)
> That one's pretty nasty.

This is what mod_perl, mod_python, etc have done to this point. Content
generators that have large content have been using ap_rwrite. We can fix
those, but the point is to keep the ap_r* APIs working so that we don't
create too high of a bar for module authors.

> >*) ap_rprintf(r, "<D:compare-report>%s</D:compare-report>", report)
> >    report == 200k string
> As is this one.

hehe... Note that the above construct actually works very well in 1.3. As
the vprintf() is performed, it is flushing directly to the network. The
working set characteristics are great (a fixed-size formatting buffer).
Point being that (since it has nice perf characteristics) it is out there in
module code today.

My patch already handles the first, and can have a fixed-size working set
for the second. (both Ryan and I will need to do the vformatter stuff to
properly deal with ap_[v]rprintf; we haven't bothered with our patches since
that is a straight-forward post-patch)


Greg Stein,

View raw message