|
Boost : |
From: Douglas Gregor (dgregor_at_[hidden])
Date: 2007-12-19 08:40:12
Phil Endecott wrote:
> Dear All,
>
> In November Sergey Skorniakov wrote to this list asking about the
> non-thread-safety of Boost.Function and consequently of Boost.Thread
> itself. Steven Watanbee replied pointing out that the problem is
> resolved in the trunk. See: http://thread.gmane.org/gmane.comp.lib.boost.devel/167877
>
> My thought at the time was "chocolate teapot". I put understanding
> this issue on my to-do list and it has finally got to the top.
> However, looking at the trac pages that Steven linked to, I am none the
> wiser; they contain patches but with no comments in the code and don't
> mention thread safety in the commit messages.
>
The root of the problem was some dynamic initialization in the vtable
code, which is rarely (if ever?) thread-safe. The problem is that the
compiler turns code like this:
static T some_value = foo();
Into something like this:
static bool some_value_initialized;
static T some_value;
if (!some_value_initialized) {
some_value_initialized = true;
some_value = foo();
}
> So can someone please help me understand the scope of this problem? i.e.
>
> - Are all uses of Boost.Function affected, or only certain uses (e.g.
> member functions vs. free functions)?
>
All uses.
> - What exactly is the race between? E.g. if I know that I'll never
> create two threads at the same time, do I still need to worry about
> other uses of Boost.Function that may be concurrent? Is the race
> between creating the function objects or between using them, or both?
>
The race will occur if you construct or assign to two boost::function
objects:
- that have the same type, and
- with target function objects of the same type, and
- you have never completely constructed/assigned to a
boost::function object of that type with that target function object type
> - Can I avoid the problem by using a new version of Boost.Function,
> without upgrading other libraries? (Is Boost.Function header-only?)
>
Yes, you can grab function_base.hpp and function_template.hpp from the
Boost trunk, overwrite the ones in 1.34.1, and you'll be fine. You
should recompile anything that depends on Function (e.g., the threads
library), but Function itself is header-only.
> - What would the symptom of failure be? I'm currently debugging a
> double-free somewhere below std::string::assign, which is probably unrelated.
>
The symptom is a segmentation fault inside Boost.Function itself,
because one thread's initialization of the vtable (a static) has claimed
to be complete (e.g., some_value_initialized has been set to true) and
another thread comes through and tries to dereference the NULL vtable
pointer (which the other thread is filling in), then dies. If you've hit
this problem, you'd know; it's very limited in scope.
> I'm also curious to know how much more serious than this a bug would
> need to be before a Boost release would be recalled, or a new
> point-release released, or an announcement made on the Boost web page
> (which links to bugs fixed in 1.34.1, but not bugs introduced). Surely
> there aren't many users of Boost.Thread who are happy to use a
> non-thread-safe thread library.....
>
This should have gone on the web page, at the very least, and I'll do so
now.
- Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk