httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Bligh <a...@alex.org.uk>
Subject Re: Bucket brigade & filter thread safety
Date Mon, 10 Sep 2012 08:47:53 GMT
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

Mime
View raw message