C++ io, thread safety, and setlocale
Loren James Rittle
rittle@latour.rsch.comm.mot.com
Tue Apr 22 01:20:00 GMT 2003
In article <16036.35939.427539.561931@localhost.localdomain>,
John Ruttenberg<rutt@chezrutt.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
be accepted.
> 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
do:
Look for all calls to setlocale of this form:
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale([...]);
[...];
setlocale(LC_ALL, __old);
To wit:
config/locale/generic/c_locale.cc
config/locale/generic/c_locale.h
config/locale/generic/time_members.cc
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.
Regards,
Loren
More information about the Libstdc++
mailing list