The following makes the C++98 locale init path follow the way the
C++11 performs initialization. This way we deal with pthread_once
failing, falling back to non-threadsafe initialization which, given we
initialize from the library, should be serialized by the dynamic
loader already.
PR libstdc++/112351
libstdc++-v3/
* src/c++98/locale.cc (locale::facet::_S_initialize_once):
Check whether _S_c_locale is already initialized.
(locale::facet::_S_get_c_locale): Always perform non-threadsafe
init when threadsafe init failed.
void
locale::facet::_S_initialize_once()
{
+ // Need to check this because we could get called once from
+ // _S_get_c_locale() when the program is single-threaded, and then again
+ // (via __gthread_once) when it's multi-threaded.
+ if (_S_c_locale)
+ return;
+
// Initialize the underlying locale model.
_S_create_c_locale(_S_c_locale, _S_c_name);
}
#ifdef __GTHREADS
if (__gthread_active_p())
__gthread_once(&_S_once, _S_initialize_once);
- else
#endif
- {
- if (!_S_c_locale)
- _S_initialize_once();
- }
+ if (__builtin_expect (!_S_c_locale, 0))
+ _S_initialize_once();
return _S_c_locale;
}