This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Further fix for 12658
On Thu, Jul 29, 2004 at 07:27:34PM +0200, Paolo Carlini wrote:
> PR libstdc++/12658 (continued)
> * src/locale_init.cc (locale::locale, locale::global): Use
> a single locale_mutex instead of two separate mutexes.
I have been thinking about this, and discussing it with local
colleagues. We have concluded that it is wrong to put mutex
locking in the locale default constructor.
The policy throughout the library is that it is the responsibility
of the user to synchronize access to visibly-shared or global
objects. We don't promise anything to a program with two threads
that happen to say cout.rdbuf()->sputc('!') at the same time; the
streambuf will very likely be corrupted. This is deliberate.
The situation with locales is the same. Constructing a default
locale and setting the global locale it copies from at the same
time is a race. Even if we serialize it, the locale constructed
will be wrong half the time. Any program that does set the global
locale in a thread must perform its own locking, anyway, to get
sensible results.
This matters because default locales may be created frequently,
via default arguments to standard library functions. Unnecessary
mutex calls are quite expensive (particularly on MacOSix). Any
program that *does* take care to synchronize its usage (or, more
likely, doesn't need it, because it sets its global locale before
spawning threads) is penalized, just to help paper over bugs in
programs that don't.
Now, the case that Petur presents is interesting because of the
invisibility of the use of locale::locale(). It might not be
unreasonable to move the mutex out of locale::locale() and into
ios_base::ios_base(). That constructor (with ios(), and
iostream(), and fstream() coming after) is pretty expensive
anyway. However, his example seems far from compelling: why
does the code that uses fprintf set the C++ locale, and not just
the C locale?
Suppose we did move the locking; how about user code that uses
locale() implicitly? Cases where the user code derives from
ios_base are taken care of magically. Any others are the user's
responsibility, as for any other global resource. Let them make
their own mutex, if they really want to set the global locale in
some thread.
Nathan Myers
ncm@cantrip.org