Jean-Marc Lasgouttes wrote: > Le 24/11/2014 21:53, Georg Baum a écrit : >> >> I guess the basic principle how copy-on-write works is clear? If not, see >> e.g. http://en.wikipedia.org/wiki/Copy-on-write. >> >> The problem is not the read access. This is safe. The problem is write >> access and can be illustrated by the following code:
Oops, this is not 100% correct. The problem _might_ actually also be read access, at least in one special case: Creating a copy of a const string. >> std::string s1("foo"); >> std::string s2(a); This was wrong, it should have been read std::string s2(s1); >> std::string s3 = s1; > > OK, could you know explain the same in terms of Language::babel(), which > is a const function? Between which objects is the representation shared? The fact that Language::babel() is const does not matter, since std::basic_string::_M_rep() lies: It is a const method but returns a non- const pointer to internal data. Therefore Language::babel_ can be (and is) modified each time a copy is made through the const accessor Language::babel(). During export a lot of these copies is being made, e.g. in output_latex.cpp. Creating the copy is a subset of the example I showed: If you don't look at the subsequent assignment, but compare only the difference after executing the first and second line, then it looks like this: std::string s1("foo"); assert(s1._M_rep()->_M_refcount == 0); Now do the assignment: std::string s2(s1); assert(s1._M_rep()->_M_refcount == 1); Whether this is a race condition depends on whether increasing the ref counter is atomic or not. The wikipedia page mentions that it can be implemented in a thread-safe way without using locks by compare-and-swap (see http://en.wikipedia.org/wiki/Compare-and-swap), but the actual implementation is so complicated that I could not verify whether this is used at a quick glance. I only know that no locks are used. So my whole theory might be wrong actually, we'll need further investigation. > It might be that understanding that is useless because the problem is > general as you say. But it might happen too that it helps us to > understand better what happens. No, I think it helps, since this is a little bit different from the previous example. Actually I don't know if a copy of Language::babel() is modified later. Georg