On Sun, 7 Jan 2001 [EMAIL PROTECTED] wrote:
>
> > as near as i can tell the correct fix to this problem is to fix the
> > ap_brigade_putstr and _printf and related functions to do buffering a la
> > apache-1.3.
>
> Those functions aren't used anyplace, so modifying them won't help this
> problem. The solution is to modify ap_r* functions in Apache to buffer
> correctly. The problem is that Apache's mod_autoindex is using the old
> ap_r* functions instead of using the buckets directly in a sane way.
ok this is silly talking on both lists. i suppose i shouldn't have even
bothered posting anything here since this is clearly a cross httpd/apr
issue.
as i just posted to new-httpd, what i said is essentially true.
ap_rprintf results in the bucket printf... ap_rputs does essentially the
same (one-copy) thing as bucket_putstr.
> > my suggestion is to allocate 4k buffers, and put them into the brigade
> > only when they're full, and use a 1.3-style bprintf/bputs which write
> > direct into these buffers.
>
> Yes, but the buffer doesn't belong in the bucket code IMO, it belongs in
> the Apache code.
oh so buffers aren't needed in any of the other APR users? ha.
> The problem there, is that once we start to buffer, you
> can't use a combination of the bucket functions and the ap_r*
> functions.
sounds like an API problem then.
> The second question is where would the buffer live? In the
> old BUFF code, it was easy, because there was only one BUFF per
> request. Now, we have multiple buckets per request. We could put the
> buffer in the brigade itself, but that makes the brigade much more
> heavy-weight than it is right now. One of the very nice things about the
> current brigades, is that they are so light-weight. We can drop them on
> the ground, and let the pool worry about them. If we are allocating a 4k
> buffer inside of them, we really have to take the brigade outside of the
> pool and use malloc/free on it, which takes away some security.
dude, buckets aren't "light-weight"... look at the malloc()s and the
writev() crud. that's not light weight. as far as you've explained to me
so far you don't have a good solution for either of these problems.
look at 2.0 ap_rputs:
bb = ap_brigade_create(r->pool);
b = ap_bucket_create_transient(str, len);
AP_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(r->output_filters, bb);
look at 1.3 ap_rputs:
rcode = ap_bputs(str, r->connection->client);
and 1.3 ap_bputs:
int i, j = strlen(x);
i = ap_bwrite(fb, x, j);
tada. 2.0 allocates a brigade, a bucket, a memory region, copies into the
memory region, appends it to a list.
1.3 allocates nothing, and copies to the final output buffer.
1.3 is light weight.
> When I originally wrote some of the bucket code, I had heap buckets
> always allocate a 4k buffer, and if we were adding to the end of a
> brigade that has a heap at the end, we just appended the new data into
> the last bucket. This ends up being a very difficult thing to do
> well.
it's difficult, so? look at the 1.3 BUFF and tell me it wasn't difficult
to get right :)
> We have a coalesce filter in Apache, that coalesces multiple buckets in
> the same brigade into a single bucket. This is one solution to not write
> such small blocks of data.
like i said, coalesce is the wrong answer. coalesce is pretty in the
abstract sense, but makes zero practical sense. it turns a one-copy
implementation into a two-copy implementation (with even more memory
allocation).
> I personally don't mind stupid generators performing badly. I would much
> rather just re-write them to work well, than to try to force the old API
> to perform as well as the new API.
i don't consider mod_autoindex "stupid". are you aware that PHP uses
rputs/etc. as well? i don't consider PHP stupid either.
the old API was convenient for the module programmer. the new API is
convenient for you. that's the wrong solution.
-dean