Is ostream operator<< in libstdc++ thread-hostile?
Asked Answered
J

1

11

ostream operator<< uses num_put::put() for number formatting. I'm trying to follow the code. I'll link to OSX files but similar files appear on some other systems I looked at. It seems to me that num_put::put() calls num_put::do_put(), which calls
num_put::_M_insert_float(), which calls __convert_from_v():

http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/c++locale.h
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.tcc
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.h

__convert_from_v() checks the current global locale, and if it's different from "C" then it calls setlocale() to set the global locale to "C", then uses vsnprintf() to format the number, then calls setlocale() again to revert to the old locale.

Since setlocale() affects all threads, it would seem that calling ostream operator<< with a floating point number is unsafe in a multi-threaded application which has the global locale set to something else than "C". But that would be very strange, so what am I missing? Thanks!

Javed answered 31/3, 2014 at 4:34 Comment(3)
It may be that the libstdc++ implementation on OS X does have this problem. It's known to have other issues, especially where many locale features aren't implemented fully (it just uses the generic locale model on OS X). libstdc++ is not getting updated on OS X. Instead libc++ is the standard c++ library implementation on OS X going forward and you should try to use that.Ironstone
I updated my answer, it isn't an issue because GCC on anything but linux doesn't support locales.Tedtedd
@JonathanWakely That's good to know. In which version was xlocale support added? (The version used in this question is 4.2.1, which is old enough that I'm pretty sure it didn't have xlocale support.)Ironstone
T
4

The latest draft (N3936) specifically warns against this:

§ 18.10

6 A call to the setlocale function may introduce a data race with other calls to the setlocale function or with calls to functions that are affected by the current C locale. The implementation shall behave as if no library function other than locale::global() calls the setlocale function.

More recent versions of GCC limit the call to LC_NUMERIC instead of LC_ALL, and if you use glibc > 2.2 the implementation avoids the problem altogether by calling uselocale which only modifies the current thread (not much use for you on OSX I guess…).

Edit: I had a better look at the source

Although issues could potentially occur with the generic locale model if a function that depends on the C locale is called from another thread while __convert_from_v or another function modifies the C locale, the only supported locale for the generic locale model is "C" (which is the locale set during startup), so this isn't an issue unless support for other locales is added to the generic model.

The only time this could be an issue is if gcc is built with the gnu locale model and glibc is <= 2.2, which isn't going to happen on OSX.

Tedtedd answered 31/3, 2014 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.