This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]