Am Dienstag, den 02.01.2007, 01:14 -0800 schrieb Drew Bertola:
> line 91 looks like this:
>
> apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);
>
> Also, it only happens if I use
>
> APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
Ah, understood.
You don't mention this, but you probably have a
for ( e = APR_BRIGADE_FIRST(bb) ;
e != APR_BRIGADE_SENTINEL(bb) ;
e = APR_BUCKET_NEXT(e) ) {
for your loop. Right?
So if you _move_ e to another brigade, the e != APR_BRIGADE_SENTINEL(bb)
will never be fullfilled and APR_BUCKET_NEXT(e) will step through the
wrong brigade and will treat the sentinel as a bucket. This causes the
observed segfault.
You could instead copy the bucket using
/**
* Copy a bucket.
* @param e The bucket to copy
* @param c Returns a pointer to the new bucket
*/
#define apr_bucket_copy(e,c) (e)->type->copy(e, c)
And then delete the bucket at the end of the loop using
/**
* Delete a bucket by removing it from its brigade (if any) and then
* destroying it.
* @remark This mainly acts as an aid in avoiding code verbosity. It is
* the preferred exact equivalent to:
* <pre>
* APR_BUCKET_REMOVE(e);
* apr_bucket_destroy(e);
* </pre>
* @param e The bucket to delete
*/
#define apr_bucket_delete(e) do { \
APR_BUCKET_REMOVE(e); \
apr_bucket_destroy(e); \
} while (0)
Since buckets do reference counting this is not copying of the data, so
its relatively cheap. There are other solutions, which work equally
well.
Sincerely,
Joachim