2009-12-18 Jimmy Guo <jguo@yahoo-inc.com> PR libstdc++/40088 * src/locale_init.cc (locale::locale()): Optimize the common case where _S_global still points to _S_classic. --- libstdc++-v3/src/locale_init.cc (revision 155341) +++ libstdc++-v3/src/locale_init.cc (revision 155343) @@ -100,9 +100,25 @@ namespace std locale::locale() throw() : _M_impl(0) { _S_initialize(); - __gnu_cxx::lock sentry(__gnu_internal::locale_mutex); - _S_global->_M_add_reference(); + + // Checked locking to optimize the common case where _S_global + // still points to _S_classic (locale::_S_initialize_once()): + // - If they are the same, just increment the reference count and + // we are done. This effectively constructs a C locale object + // identical to the static c_locale. + // - Otherwise, _S_global can and may be destroyed due to + // locale::global() call on another thread, in which case we + // fall back to lock protected access to both _S_global and + // its reference count. _M_impl = _S_global; + if (_M_impl == _S_classic) + _M_impl->_M_add_reference(); + else + { + __gnu_cxx::lock sentry(__gnu_internal::locale_mutex); + _S_global->_M_add_reference(); + _M_impl = _S_global; + } } locale