Joachim Zobel wrote: > 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.
Are you sure about that? Again, makes me wish for a null output filter example. My understanding is that it would need this: - create context if it doesn't already exist. - loop through buckets (from FIRST to SENTINEL) in brigade passed to filter appending each bucket to my context's brigade. - pass my brigade to next filter. So, shouldn't this work? ... static int null_filter(ap_filter_t *f, apr_bucket_brigade *bb) { null_filter_struct *ctx = f->ctx; apr_bucket *e; /* * if we don't have a context for this filter, let's create one and * create it's bucket brigade. */ if ( ! ctx ) { f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); } /* * let's loop through the buckets passed to us. */ for( e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e) ) { /* * if the bucket is an end of stream bucket or a flush bucket, * we can pass on what we have so far and be done with this brigade. */ if ( APR_BUCKET_IS_EOS(e) || APR_BUCKET_IS_FLUSH(e) ) { APR_BRIGADE_INSERT_TAIL(ctx->bb, e); APR_BUCKET_REMOVE(e); ap_pass_brigade(f->next, ctx->bb); return APR_SUCCESS; } APR_BRIGADE_INSERT_TAIL(ctx->bb, e); APR_BUCKET_REMOVE(e); } ap_pass_brigade(f->next, ctx->bb); return APR_SUCCESS; } I'm not sure about these things: - do I need to look out for APR_BUCKET_IS_EOS or APR_BUCKET_IS_FLUSH or are they implicit before APR_BRIGADE_IS_SENTINEL? - do I need to use ap_pass_brigade()? I've used it here before returning. -- Drew