Hi, while investigating http://www.lyx.org/trac/ticket/9336 I found out a fundamental problem with our multithreaded export: The GNU libstdc++ gives only a relatively weak thread-safety guarantee about std::basic string. It is not completely thread-safe in the POSIX sense. The reason for this lies in the employed copy-on-write technique, which is not used in other STL implementations such as the one in clang or MSVC. It is even explicitly forbidden in the new C++11 standard, and the gcc folks already acknowledged that they will get rid of it, but since this is an ABI incompatible change they want to wait until they have several such changes to do all in one go. For details please see the excellent gcc bug report by James Kanze (who is a C++ expert) at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334, especially https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334#c21, which describes almost exactly the situation we have with the document language.
This looks all rather theoretical, but in practice it means that it is quite easy to produce crashes if you use LyX built with #define EXPORT_in_THREAD 1 and gcc, and start an export, depending on the document (master-child setups seem to be much more vulnerable). The thing which seems to be most affected is Language::babel_, which is copied a lot, but problems could arise from all std::string and docstring variables. What do we do now? I can think of several alternatives: 1) Do nothing, because my findings are incorrect. I don't believe that of course, but I would appreciate it if somebody would try to find flaws in my reasoning. 2) Disable EXPORT_in_THREAD if GNU libstdc++ is found. This is an easy and safe solution, with the disadvantage that it removes a feature (but I think that this is much better than risking crashes). 3) Derive an own class lyx::basic_string from std::basic_string which circumvents copy-on-wrtite in the copy-constructor and assignment operator by creating the copy from c_str(). Then use it namespace lyx { typedef basic_string<char_type> docstring; typedef basic_string<char> string; } and replace all occurances of std::string with lyx::string. This would of course need a lot of testing, but I believe it could work. 4) Do not use std::basic_string at all, but an own implementation which could be stolen from STLport or clang (if the licenses permit that and are compatible to the GPL, I did not check that). However, I believe that this would create lots of interface problems with other libraries. Does anybody see any other solution? I think for the stable branch we do not really have any choice and need to implement 2). The other question is: What can we learn for the future? AFAIK EXPORT_in_THREAD was developed on windows, and it was probably well tested on that platform. However, one basic lesson to learn is that such important infrastructure changes need thorough testing on all supported platforms, and I don't think this did happen in this case. Despite qt hides many differences for us there are still a lot of platform specific issues left. Cheers, Georg