This is the mail archive of the
mailing list for the libstdc++ project.
Re: C++ io, thread safety, and setlocale
In article <16036 dot 35939 dot 427539 dot 561931 at localhost dot localdomain>,
John Ruttenberg<rutt at chezrutt dot com> writes:
>> > Pehaps this is a FAQ, but I couldn't find anything.
>> You could find more details about this in section 5.6 of
>> libstdc++-v3/docs/html/faq/index.html . Note well the exact words
>> where we weasel out in various cases; mainly involving unknown libc
>> implementation. One could conceive of a thread implementation where
>> setlocale acted on a per-thread basis but I'd agree in my experience
>> this is unlikely.
libstdc++-v3 assumes that it may use the system's libc. If it isn't
thread-safe in all regards, then various features in libstdc++-v3 may
not be thread-safe. Unless you are getting libstdc++-v3 from a system
packager that claims to support a stronger statement in this area, I'm
afraid that we must stand on the FSF documented situation. Patches to
improve the status quo for a system without regression elsewhere would
> OK, I read this closely, but I still don't understand. How can it be safe for
> standard library calls to use setlocale in this way?
If the system's libc supported setlocale on a per-thread basis, then
IMHO it would be quite safe given the way our implementation always
pairs the calls in a manner that is inviolate. The C89 and C99
standards say nothing about this case.
> Isn't there a per thread
> locale that you should use to make this safe? (Not that I actually know
> anything about this; I'm just trying to fight a fire.)
Not with C89 or C99; or otherwise commonly portable. Some version of
POSIX or C0x might say something about this (in the future?). Sorry.
> What do you do with
> glibc or on solaris that makes those situations work (I think they do; our
> application has been running in those environments for a long time without
> experiencing these problems.)
glibc has special support to handle the locale settings on a
per-thread basis; libstdc++-v3 uses that support. Other than using
the same code path as AIX and FreeBSD (and that Solaris documents
their implementation of setlocale to be non-thread safe), I don't know
what Solaris does that might make the situation better than other
places. Some libc implementations might handle the case where global
locale is "C" both before and after a call to setlocale() more
gracefully than others. For example, FreeBSD 4 overlays the new
setlocale directly on top of the old in a manner such that "C" -> "C"
will be a noop to all other concurrently running threads (i.e. we get
lucky - I have not studied the source for any other implementation).
Perhaps, you might check to ensure that you are running with locale "C".
>> > How can this be thread safe without some locking of some sort?
> Can I build the library in some way that will avoid the locale support in
> favor of thread support.
At the moment and to my knowledge, the hypothetical tradeoff that I
spoke about is not handled on any branch of libstdc++-v3 code that has
the improved locale support (i.e. gcc 3.1 and later). The patch is
rather contained, if someone was motivated to do it. Here is what I'd
Look for all calls to setlocale of this form:
char* __old = strdup(setlocale(LC_ALL, NULL));
If __old was exactly "C" (although there again, an implementation
could return something that isn't really parsable in this manner; thus
one would have to check enough environments to ensure this advice
actually could work), then skip both the explicit set to "C" and reset
back to __old. If someone submitted a tested patch (no regressions on
their platform; no regressions on various platforms I can easily
test), and a statement that it helps in practice for a thread test
case (ideally, you be able to submit a small test case along with a
patch); then we'd accept it. I hate to put a burden back on you, but
(a) it is a common maintainer trick and (b) I haven't ever seen the
actual problem. I could whip something up next week at the earliest.