On 25-Apr-05, at 3:36 PM, Justin Erenkrantz wrote:

--On Monday, April 25, 2005 3:06 PM -0500 Rici Lake <[EMAIL PROTECTED]> wrote:

Can you quantify that "large overhead"? In the case of a 'compliant'
filter, it consists of:

With Joe's suggestion for 'creator must destroy', this step is wholly unnecessary and only overcomplicates things. -- justin

The creator must destroy the brigade when it's done with it -- if I understand Joe correctly.


Creating and destroying a brigade on every invocation of a filter is a lot more overhead than a few extraneous unfulfilled while loops -- even if the brigade is allocated in a bucket_allocator. Even without the buildup of pool memory for the brigade objects, creating a brigade requires the registration (and later deregistration, during brigade_destroy) of a pool cleanup function.

If we accept that the contents of a brigade are "undefined" when ap_pass_brigade returns, the caller has three options:
-- call cleanup and reuse the brigade
-- call destroy (which will first call cleanup)
-- drop it on the floor and let destroy be called by the cleanup function


In no case can it make any use of the brigade's contents (they're "undefined"), so cleanup must be called just after ap_pass_brigade returns.

If ap_pass_brigade does the call itself, it reduces the number of places in the code where cleanup is called, and possibly frees resources slightly earlier in the case where the brigade creator dropped the brigade on the floor. The cost is a few extraneous if (!APR_BRIGADE_EMPTY(bb)) statements (or moral equivalent). This is actually a macro which expands to a fairly simple pointer comparison.

That's hardly a complication -- it's a simplification (from the perspective of the caller of ap_pass_brigade. And it's hardly an enormous overhead.

/me continues the tradition of creating flames out of bucket brigades. You'd think it would be the reverse :)






Reply via email to