Ben,

Thanks for your reply.

I am suffering from very occasional corruption of the bucket brigade
which normally shows up as a corrupted pool pointer or a bogus bucket
entry in thread #1 (for instance a SEGV in apr_brigade_length).
Interestingly this is the relatively quiet input brigade which is only
ever touched by the main apache thread. It's almost as if an allocator
is not thread safe.

That's because it isn't unless you explicitly make it so (which no MPM
does).

What I'm trying to do is to use a separate allocator per thread.

However, I'm using a separate bucket allocator (see code above) and (at
least in my code) a separate pool.

They're not really separate, the sub pool is created off r->pool. You
should probably use apr_pool_create_ex() here with parent=NULL and an
allocator that you created with apr_allocator_create() +
apr_allocator_mutex_set().

OK I based this on the docs for apr_pool_create which says at
http://apr.apache.org/docs/apr/1.4/group__apr__pools.html#ga918adf3026c894efeae254a0446aed3b

: This function is thread-safe, in the sense that multiple threads can
: safely create subpools of the same parent pool concurrently. Similarly, a
: subpool can be created by one thread at the same time that another thread
: accesses the parent pool.

Have I understood that wrong?

That won't solve all your problems though. Bucket brigades are not
thread safe, you will need something to synchronize on.

So what I was trying to do was to use
a) the input bucket brigade in thread #1 (main thread)
b) the output bucket brigade in thread #2
in an attempt to avoid synchronization

But what I don't understand is whether thread #2, in writing
to the output filters (which presumably have a reference
to r->pool) will need synchronisation.

And if I have to synchronize, how do I do that in practice?
Thread #2 does and ap_fwrite/ap_flush so I can hold a mutex
there. But what do I do in thread #1, which calls ap_brigade_get
and blocks? I can't hold a mutex during that. I can make it
a non-blocking ap_brigade_get (if I understood how to do it)
but what I really need is the equivalent of a select() which
I can do with the mutex not held (or some way to drop the mutex
during the raw reads). Any ideas?

--
Alex Bligh

Reply via email to