]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++/112351 - deal with __gthread_once failure during locale init
authorRichard Biener <rguenther@suse.de>
Mon, 6 Nov 2023 10:31:40 +0000 (11:31 +0100)
committerRichard Biener <rguenther@suse.de>
Tue, 7 Nov 2023 12:55:07 +0000 (13:55 +0100)
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.

libstdc++-v3/src/c++98/locale.cc

index d308140bab7dc68d79b16340f1c045746f718ee8..1ef0c394cd739f08873b5bbd03cb2561d0dbbd10 100644 (file)
@@ -206,6 +206,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   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);
   }
@@ -216,12 +222,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #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;
   }