Sander Striker wrote:

[...]

The child thread is register in the parent thread. So, in the case of
the first created thread, a lock will be created. This does not happen
in the stub.

That eliminates the first race condition, but not the second. Consider this
usage:
* There are two global SMSs, sms1 and sms2.
* Two threads, p1 and p2, are created with sms1 as the SMS supplied to
apr_thread_create.
* Prior to the creation of p1 and p2, sms2 is unused.
* p1 creates a child thread, c1, and passes sms2 as the SMS for
apr_thread_create to use.
* p2 creates a child thread, c2, and passes sms2 as the SMS for
apr_thread_create to use.


During the last two steps, we're vulnerable to the lock creation
race condition.


Ok, I can see that. I must say though that anybody who is actually building an application like this is asking for trouble. Tell me, why would there need to be 2 global smss that are both used to pass in as a parent to thread creation. That is very awkward...

It's definitely awkward.  I could see it happening, though, if
somebody builds a library based on APR that creates a global
SMS for thread creation, and then a third party uses this library
in an application that creates its own global SMS and uses it to
create additional threads within callbacks invoked by the library's
threads.  (I'm not claiming that this is a good design, but it's a
good test of the robustness of the registration model.  And it
looks like the model can handle this example properly, by
requiring that p1 and p2 register themselves with sms2 as
noted below.)

As far as I know, this isn't a case that will ever happen in Apache,
but it's possible in APR based apps in general.  I guess there are
two ways to solve it: 1) add code to defend against the race condition,
or 2) impose a convention that says that p1 and p2 must register
themselves with sms2 before they're allowed to create any other
threads that use it.


Actually, they need to anyway. When they are _using_ an sms, which they are, in this case sms2, by passing it to apr_thread_create(). In that function sms2 is used to allocate the thread structure. This all takes place in thread p1/p2. p1 and p2 should have registered themselves with sms2 prior to using it.

Agreed.  And that resolves all the race conditions that
I was worried about.

--Brian




Reply via email to