
John Maddock wrote:
The problem only shows up on my dual-processor G5, and never seemed to happen on single-processor systems, so we have some kind of race condition. Looking more carefully at the Spirit source, I see this:
#ifdef BOOST_SPIRIT_THREADSAFE static boost::mutex mutex; boost::mutex::scoped_lock lock(mutex); #endif
I don't think that's valid, because two threads could try to initialize the static at the same time. We'd need to do some other kind of locking in here, then create the mutex on the heap.
Doug, thank you very much for tracking that down!
Right that code absolutely will create a race condition in the mutex initialisation.
If it helps any regex has a static_mutex class that is initialised with a static initialiser list (so no race condition), I've been meaning to polish this off as a formal submission, but in the mean time the code is here: boost/regex/pending/static_mutex.hpp.
This looks very nice. However, using static_mutex would create a dependency on Boost.Regex for all Spirit MT code. I hope static_mutex will eventually become a part of Boost.Thread. I changed the offending code to use boost::call_once() for mutex initialization (following a suggestion Peter Dimov made in another thread related to a similar problem). The test passes on OSL2 (darwin-gcc-3.3 toolset) now. Thanks to Doug, John, Stefan and Peter for their support! Regards, m PS: boost::call_once() takes a void(*)(). An overload of call_once that would accept a T(*)() (for T!=void) would be helpful (the value returned would simply get discarded). Send instant messages to your online friends http://au.messenger.yahoo.com