]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 2 Oct 2003 16:56:39 +0000 (16:56 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 2 Oct 2003 16:56:39 +0000 (16:56 +0000)
2003-10-02  Benjamin Kosnik  <bkoz@redhat.com>

* config/linker-map.gnu: Export _S_get_c_locale instead of
_S_c_locale object.

2003-10-02  Petur Runolfsson  <peturr02@ru.is>

* config/locale/generic/c_locale.cc
(category_names, locale::_S_categories): Const qualify.
* config/locale/gnu/c_locale.cc: Same.
* config/locale/generic/time_members.h (__timepunct::__timepunct):
Copy string contents before assigning to _M_name_timepunct,
qualify strcpy and strlen with std::.
* config/locale/gnu/time_members.h: Same.
* config/locale/gnu/messages_members.h (messages::messages):
Copy string contents before assigning to _M_name_messages,
qualify strcpy and strlen with std::.
* config/os/gnu-linux/ctype_noninline.h
(ctype<char>::classic_table()): Don't call locale::classic().
* include/bits/locale_classes.h
(locale::_S_categories): Const qualify.
(locale::_S_once, locale::_S_initialize_once,
locale::facet::_S_once, locale::facet::_S_initialize_once,
locale::facet::_S_get_c_locale): Declare.
(locale::_S_initialize): Don't define.
(locale::facet::_S_c_locale): Make private.
(locale::facet::_S_c_name): Same, const qualify.
(locale::_Impl::_Impl(facet**, size_t, bool)): Drop unused
parameters, add throw() specifier.
* include/bits/locale_facets.h (__timepunct::_M_name_timepunct,
messages::_M_name_messages): Const qualify.
* src/locale.cc
(locale::_S_once, locale::facet::_S_once): Define.
(locale::classic): Move initialization code...
(locale::_S_initialize_once): ...here.
(locale::_S_initialize): Call _S_initialize_once through
__gthread_once.
(locale::facet::_S_initialize_once): Initialize _S_c_locale.
(locale::facet::_S_get_c_locale): Call _S_initialize_once through
__gthread_once before returning _S_c_locale.
* src/localename.cc (locale::_Impl::_Impl(facet**, size_t, bool)):
Drop unused parameters, add throw() specifier, don't initialize
locale::facet::_S_c_locale and _S_c_name.

* config/locale/generic/messages_members.h:
Replace _S_c_locale with _S_get_c_locale().
* config/locale/gnu/c_locale.cc: Same.
* config/locale/gnu/messages_members.h: Same.
* config/locale/gnu/numeric_members.cc: Same.
* config/locale/gnu/time_members.cc: Same.
* config/os/gnu-linux/ctype_noninline.h: Same.
* include/bits/locale_facets.h: Same.
* include/bits/locale_facets.tcc: Same.
* src/codecvt.cc: Same.
* src/ctype.cc: Same.

From-SVN: r72040

19 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/linker-map.gnu
libstdc++-v3/config/locale/generic/c_locale.cc
libstdc++-v3/config/locale/generic/messages_members.h
libstdc++-v3/config/locale/generic/time_members.h
libstdc++-v3/config/locale/gnu/c_locale.cc
libstdc++-v3/config/locale/gnu/messages_members.h
libstdc++-v3/config/locale/gnu/numeric_members.cc
libstdc++-v3/config/locale/gnu/time_members.cc
libstdc++-v3/config/locale/gnu/time_members.h
libstdc++-v3/config/os/gnu-linux/ctype_noninline.h
libstdc++-v3/include/bits/codecvt.h
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/locale_facets.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/src/codecvt.cc
libstdc++-v3/src/ctype.cc
libstdc++-v3/src/locale.cc
libstdc++-v3/src/localename.cc

index 9abb29f0fd49ee70c20b0b2f2feba2a945629777..59b6bffa2da48a9f47c5dcbde785eed1e7b603e6 100644 (file)
@@ -1,3 +1,59 @@
+2003-10-02  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * config/linker-map.gnu: Export _S_get_c_locale instead of
+       _S_c_locale object.
+
+2003-10-02  Petur Runolfsson  <peturr02@ru.is>
+
+       * config/locale/generic/c_locale.cc
+       (category_names, locale::_S_categories): Const qualify.
+       * config/locale/gnu/c_locale.cc: Same.
+       * config/locale/generic/time_members.h (__timepunct::__timepunct):
+       Copy string contents before assigning to _M_name_timepunct,
+       qualify strcpy and strlen with std::.
+       * config/locale/gnu/time_members.h: Same.
+       * config/locale/gnu/messages_members.h (messages::messages):
+       Copy string contents before assigning to _M_name_messages,
+       qualify strcpy and strlen with std::.
+       * config/os/gnu-linux/ctype_noninline.h
+       (ctype<char>::classic_table()): Don't call locale::classic().
+       * include/bits/locale_classes.h
+       (locale::_S_categories): Const qualify. 
+       (locale::_S_once, locale::_S_initialize_once,
+       locale::facet::_S_once, locale::facet::_S_initialize_once,
+       locale::facet::_S_get_c_locale): Declare.
+       (locale::_S_initialize): Don't define.
+       (locale::facet::_S_c_locale): Make private.
+       (locale::facet::_S_c_name): Same, const qualify.
+       (locale::_Impl::_Impl(facet**, size_t, bool)): Drop unused
+       parameters, add throw() specifier.
+       * include/bits/locale_facets.h (__timepunct::_M_name_timepunct,
+       messages::_M_name_messages): Const qualify.
+       * src/locale.cc
+       (locale::_S_once, locale::facet::_S_once): Define.
+       (locale::classic): Move initialization code...
+       (locale::_S_initialize_once): ...here.  
+       (locale::_S_initialize): Call _S_initialize_once through
+       __gthread_once.
+       (locale::facet::_S_initialize_once): Initialize _S_c_locale.
+       (locale::facet::_S_get_c_locale): Call _S_initialize_once through
+       __gthread_once before returning _S_c_locale.
+       * src/localename.cc (locale::_Impl::_Impl(facet**, size_t, bool)):
+       Drop unused parameters, add throw() specifier, don't initialize
+       locale::facet::_S_c_locale and _S_c_name.
+       
+       * config/locale/generic/messages_members.h:
+       Replace _S_c_locale with _S_get_c_locale().
+       * config/locale/gnu/c_locale.cc: Same.
+       * config/locale/gnu/messages_members.h: Same.
+       * config/locale/gnu/numeric_members.cc: Same.
+       * config/locale/gnu/time_members.cc: Same.
+       * config/os/gnu-linux/ctype_noninline.h: Same.
+       * include/bits/locale_facets.h: Same.
+       * include/bits/locale_facets.tcc: Same.
+       * src/codecvt.cc: Same.
+       * src/ctype.cc: Same.
+
 2003-10-02  Carlo Wood  <carlo@alinoe.com>
 
        * include/bits/demangle.h (demangle<Allocator>::symbol(char const*)):
index fa54dcf1a05ed793abf94a05d50705a9c6220c0e..d0ab03c191d9d1840bb4b313061c24a81f44f61b 100644 (file)
@@ -32,7 +32,7 @@ GLIBCXX_3.4 {
       std::logic_error*;
       std::locale::[A-Za-e]*;
       std::locale::facet::[A-Za-z]*;
-      std::locale::facet::_S_c_locale; 
+      std::locale::facet::_S_get_c_locale*;    
       std::locale::facet::_S_clone_c_locale*;
       std::locale::facet::_S_create_c_locale*;
       std::locale::facet::_S_destroy_c_locale*;
index 5a211a187df2f2d7f5383852608ce493b709f2a6..a9d9537ffdb6e88ea3132e138b54c88ed86b0610 100644 (file)
@@ -234,7 +234,7 @@ namespace std
 
 namespace __gnu_cxx
 {
-  const char* category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
+  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
     {
       "LC_CTYPE", 
       "LC_NUMERIC",
@@ -247,5 +247,5 @@ namespace __gnu_cxx
 
 namespace std
 {
-  const char** locale::_S_categories = __gnu_cxx::category_names;
+  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
 }  // namespace std
index 2d588049c4f751264ff87c39480bf3a9f14e19d3..3e9122e880fc3696676263ebf4188446b9a7b5f2 100644 (file)
   template<typename _CharT>
      messages<_CharT>::messages(size_t __refs)
      : facet(__refs)
-     { _M_c_locale_messages = _S_c_locale; }
+     { _M_c_locale_messages = _S_get_c_locale(); }
 
   template<typename _CharT>
      messages<_CharT>::messages(__c_locale, const char*, size_t __refs) 
      : facet(__refs)
-     { _M_c_locale_messages = _S_c_locale; }
+     { _M_c_locale_messages = _S_get_c_locale(); }
 
   template<typename _CharT>
     typename messages<_CharT>::catalog 
index 8db2cb53ed85144417ceb1128c9b1f4a201cf90e..2da37eb95b347ac1ef5472eaa8359dd0f1f0006b 100644 (file)
@@ -55,8 +55,9 @@
                                     size_t __refs) 
     : facet(__refs), _M_data(NULL)
     { 
-      _M_name_timepunct = new char[strlen(__s) + 1];
-      strcpy(_M_name_timepunct, __s);
+      char* __tmp = new char[std::strlen(__s) + 1];
+      std::strcpy(__tmp, __s);
+      _M_name_timepunct = __tmp;
       _M_initialize_timepunct(__cloc); 
     }
 
index 1309c0308eb576f462db279b92c6acf872ec2eb8..3c7d258e875808523540e3a9c47146f274036931 100644 (file)
@@ -180,7 +180,7 @@ namespace std
   void
   locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
   {
-    if (_S_c_locale != __cloc)
+    if (_S_get_c_locale() != __cloc)
       __freelocale(__cloc); 
   }
 
@@ -191,7 +191,7 @@ namespace std
 
 namespace __gnu_cxx
 {
-  const char* category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
+  const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
     {
       "LC_CTYPE", 
       "LC_NUMERIC",
@@ -210,5 +210,5 @@ namespace __gnu_cxx
 
 namespace std
 {
-  const char** locale::_S_categories = __gnu_cxx::category_names;
+  const char* const* const locale::_S_categories = __gnu_cxx::category_names;
 }  // namespace std
index 48dcf32dd2e43f60fd1ee88db626f2dce8346484..fc2bb2eceb5bce743cc71e1f97a0cca385fc8068 100644 (file)
@@ -41,7 +41,7 @@
 #if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2))
        _M_name_messages = _S_c_name;
 #endif
-       _M_c_locale_messages = _S_c_locale
+       _M_c_locale_messages = _S_get_c_locale()
      }
 
   template<typename _CharT>
@@ -51,8 +51,9 @@
      : facet(__refs)
      {
 #if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)) 
-       _M_name_messages = new char[strlen(__s) + 1];
-       strcpy(_M_name_messages, __s);
+       char* __tmp = new char[std::strlen(__s) + 1];
+       std::strcpy(__tmp, __s);
+       _M_name_messages = __tmp;
 #endif
        _M_c_locale_messages = _S_clone_c_locale(__cloc); 
      }
 #if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2))
        if (this->_S_c_name != this->_M_name_messages)
         delete [] this->_M_name_messages;
-       this->_M_name_messages = new char[strlen(__s) + 1];
-       strcpy(this->_M_name_messages, __s);
+       char* __tmp = new char[std::strlen(__s) + 1];
+       std::strcpy(__tmp, __s);
+       this->_M_name_messages = __tmp;
 #endif
        _S_destroy_c_locale(this->_M_c_locale_messages);
        _S_create_c_locale(this->_M_c_locale_messages, __s); 
index 36e2365f664afd7c93d0a8cd176eee97c9bb2c37..d97f0dc6f5000c77d29a2636caf1da71f2bd285d 100644 (file)
@@ -103,7 +103,7 @@ namespace std
          _M_data->_M_thousands_sep = L',';
 
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-         __c_locale __old = __uselocale(_S_c_locale);
+         __c_locale __old = __uselocale(_S_get_c_locale());
 #endif
          // Use ctype::widen code without the facet...
          unsigned char uc;
index e49b66b256f29a0afce29371839de8389834e287..62dc843dfd7845bfee4df3ffd612a036debd3dde 100644 (file)
@@ -66,7 +66,7 @@ namespace std
       if (!__cloc)
        {
          // "C" locale
-         _M_c_locale_timepunct = _S_c_locale;
+         _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = "%m/%d/%y";
          _M_data->_M_date_era_format = "%m/%d/%y";
@@ -214,7 +214,7 @@ namespace std
       if (!__cloc)
        {
          // "C" locale
-         _M_c_locale_timepunct = _S_c_locale;
+         _M_c_locale_timepunct = _S_get_c_locale();
 
          _M_data->_M_date_format = L"%m/%d/%y";
          _M_data->_M_date_era_format = L"%m/%d/%y";
index 6badaacbfa0b6e017ce9e42ab8e8d85a48081fff..3129cd1769480099e407db6c5e998bf8c5d9613a 100644 (file)
@@ -61,8 +61,9 @@
     : facet(__refs), _M_data(NULL)
     { 
 #if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2))
-      _M_name_timepunct = new char[strlen(__s) + 1];
-      strcpy(_M_name_timepunct, __s);
+      char* __tmp = new char[std::strlen(__s) + 1];
+      std::strcpy(__tmp, __s);
+      _M_name_timepunct = __tmp;
 #endif
       _M_initialize_timepunct(__cloc); 
     }
index 01ef01f4065baa48b2798425f76c739708bf90f1..83a93cb9dfed57e014b561cf7e70b451499f5b5e 100644 (file)
 #if _GLIBCXX_C_LOCALE_GNU
   const ctype_base::mask*
   ctype<char>::classic_table() throw()
-  {
-    locale::classic();
-    return _S_c_locale->__ctype_b;
-  }
+  { return _S_get_c_locale()->__ctype_b; }
 #else
   const ctype_base::mask*
   ctype<char>::classic_table() throw()
@@ -87,7 +84,7 @@
 #endif
     setlocale(LC_CTYPE, __old);
     free(__old);
-    _M_c_locale_ctype = _S_c_locale;
+    _M_c_locale_ctype = _S_get_c_locale();
   }
 #endif
 
@@ -95,7 +92,7 @@
   ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) : 
   __ctype_abstract_base<char>(__refs), _M_del(__table != 0 && __del)
   {
-    _M_c_locale_ctype = _S_c_locale
+    _M_c_locale_ctype = _S_get_c_locale()
     _M_toupper = _M_c_locale_ctype->__ctype_toupper;
     _M_tolower = _M_c_locale_ctype->__ctype_tolower;
     _M_table = __table ? __table : _M_c_locale_ctype->__ctype_b;
 #endif
     setlocale(LC_CTYPE, __old);
     free(__old);
-    _M_c_locale_ctype = _S_c_locale;
+    _M_c_locale_ctype = _S_get_c_locale();
   }
 #endif
 
index f013142ffea7d38725b2b6bf673d4d7c529dcd7a..1d123a93c6491c04c7404ee5383abd0665c51c74 100644 (file)
       codecvt_byname(const char* __s, size_t __refs = 0) 
       : codecvt<_InternT, _ExternT, _StateT>(__refs)
       { 
-       if (this->_M_c_locale_codecvt != this->_S_c_locale)
-         _S_destroy_c_locale(this->_M_c_locale_codecvt);
+       _S_destroy_c_locale(this->_M_c_locale_codecvt);
        _S_create_c_locale(this->_M_c_locale_codecvt, __s); 
       }
 
index 5ecbf7d6516e2a20db195b36f3465df055896acb..d9502bd2ae02face301a68a6b6171ac505946d10 100644 (file)
@@ -46,6 +46,7 @@
 #include <cstring>             // For strcmp.
 #include <string>
 #include <bits/atomicity.h>
+#include <bits/gthr.h>
 
 namespace std
 {
@@ -139,7 +140,7 @@ namespace std
     _Impl*             _M_impl;  
 
     // The "C" reference locale
-    static _Impl*      _S_classic; 
+    static _Impl*       _S_classic;
 
     // Current global locale
     static _Impl*      _S_global;  
@@ -148,7 +149,7 @@ namespace std
     // NB: locale::global() has to know how to modify all the
     // underlying categories, not just the ones required by the C++
     // standard.
-    static const char** _S_categories;
+    static const char* const* const _S_categories;
 
     // Number of standard categories. For C++, these categories are
     // collate, ctype, monetary, numeric, time, and messages. These
@@ -162,15 +163,18 @@ namespace std
     // and LC_IDENTIFICATION.
     static const size_t _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES;
 
+#ifdef __GTHREADS
+    static __gthread_once_t _S_once;
+#endif
+
     explicit 
     locale(_Impl*) throw();
 
-    static inline void  
-    _S_initialize()
-    { 
-      if (!_S_classic) 
-       classic();  
-    }
+    static void  
+    _S_initialize();
+
+    static void
+    _S_initialize_once();
 
     static category  
     _S_normalize_category(category);
@@ -189,13 +193,20 @@ namespace std
 
     mutable _Atomic_word               _M_references;
 
-  protected:
     // Contains data from the underlying "C" library for the classic locale.
-    static __c_locale                  _S_c_locale;
+    static __c_locale                   _S_c_locale;
 
     // String literal for the name of the classic locale.
-    static char                                _S_c_name[2];
-    
+    static const char                  _S_c_name[2];
+
+#ifdef __GTHREADS
+    static __gthread_once_t            _S_once;
+#endif
+
+    static void 
+    _S_initialize_once();
+
+  protected:
     explicit 
     facet(size_t __refs = 0) throw() : _M_references(__refs ? 1 : 0)
     { }
@@ -213,6 +224,10 @@ namespace std
     static void
     _S_destroy_c_locale(__c_locale& __cloc);
 
+    // Returns data from the underlying "C" library for the classic locale.
+    static __c_locale
+    _S_get_c_locale();
+
   private:
     inline void
     _M_add_reference() const throw()
@@ -332,7 +347,7 @@ namespace std
 
     _Impl(const _Impl&, size_t);
     _Impl(const char*, size_t);
-    _Impl(facet**, size_t, bool);
+    _Impl(size_t) throw();
 
    ~_Impl() throw();
 
index 234a0cf269e34753e8483faf56fffa3a7acb31c5..96fc3a0da35d5ffe7b7359877e138e31b06704e1 100644 (file)
@@ -1046,7 +1046,7 @@ namespace std
       explicit 
       collate(size_t __refs = 0)
       : facet(__refs)
-      { _M_c_locale_collate = _S_c_locale; }
+      { _M_c_locale_collate = _S_get_c_locale(); }
 
       explicit 
       collate(__c_locale __cloc, size_t __refs = 0) 
@@ -1261,7 +1261,7 @@ namespace std
     protected:
       __cache_type*                    _M_data;
       __c_locale                       _M_c_locale_timepunct;
-      char*                            _M_name_timepunct;
+      const char*                      _M_name_timepunct;
 
     public:
       static locale::id                id;
@@ -1898,7 +1898,7 @@ namespace std
       // Underlying "C" library locale information saved from
       // initialization, needed by messages_byname as well.
       __c_locale                       _M_c_locale_messages;
-      char*                            _M_name_messages;
+      const char*                      _M_name_messages;
 
     public:
       static locale::id                id;
index cbfed442c8d1ec5da92885f629303ba6c1ba7a44..ad5c59bf9b46f97057c8e70bbf7a8021eb62d014 100644 (file)
@@ -432,7 +432,7 @@ namespace std
 
          unsigned long __ul; 
          std::__convert_to_v(__xtrc.c_str(), __ul, __err, 
-                             _S_c_locale, __base);
+                             _S_get_c_locale(), __base);
          if (!(__err & ios_base::failbit) && __ul <= 1)
            __v = __ul;
          else 
@@ -493,7 +493,8 @@ namespace std
       string __xtrc;
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err,
+                         _S_get_c_locale(), __base);
       return __beg;
     }
 
@@ -507,7 +508,8 @@ namespace std
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
       unsigned long __ul;
-      std::__convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __ul, __err,
+                         _S_get_c_locale(), __base);
       if (!(__err & ios_base::failbit) 
          && __ul <= numeric_limits<unsigned short>::max())
        __v = static_cast<unsigned short>(__ul);
@@ -526,7 +528,8 @@ namespace std
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
       unsigned long __ul;
-      std::__convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __ul, __err,
+                         _S_get_c_locale(), __base);
       if (!(__err & ios_base::failbit) 
          && __ul <= numeric_limits<unsigned int>::max())
        __v = static_cast<unsigned int>(__ul);
@@ -544,7 +547,8 @@ namespace std
       string __xtrc;
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err,
+                         _S_get_c_locale(), __base);
       return __beg;
     }
 
@@ -558,7 +562,8 @@ namespace std
       string __xtrc;
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err,
+                         _S_get_c_locale(), __base);
       return __beg;
     }
 
@@ -571,7 +576,8 @@ namespace std
       string __xtrc;
       int __base;
       __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err,
+                         _S_get_c_locale(), __base);
       return __beg;
     }
 #endif
@@ -585,7 +591,8 @@ namespace std
       string __xtrc;
       __xtrc.reserve(32);
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err,
+                         _S_get_c_locale());
       return __beg;
     }
 
@@ -598,7 +605,7 @@ namespace std
       string __xtrc;
       __xtrc.reserve(32);
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       return __beg;
     }
 
@@ -611,7 +618,7 @@ namespace std
       string __xtrc;
       __xtrc.reserve(32);
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
-      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale);
+      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       return __beg;
     }
 
@@ -636,7 +643,8 @@ namespace std
       __io.flags(__fmt);
 
       unsigned long __ul;
-      std::__convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base);
+      std::__convert_to_v(__xtrc.c_str(), __ul, __err,
+                         _S_get_c_locale(), __base);
       if (!(__err & ios_base::failbit))
        __v = reinterpret_cast<void*>(__ul);
       else 
@@ -929,7 +937,7 @@ namespace std
 
        _S_format_float(__io, __fbuf, __mod);
        __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
-                                     _S_c_locale, __prec);
+                                     _S_get_c_locale(), __prec);
 
        // If the buffer was not large enough, try again with the correct size.
        if (__len >= __cs_size)
@@ -937,7 +945,7 @@ namespace std
            __cs_size = __len + 1; 
            __cs = static_cast<char*>(__builtin_alloca(__cs_size));
            __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
-                                         _S_c_locale, __prec);
+                                         _S_get_c_locale(), __prec);
          }
 #else
        // Consider the possibility of long ios_base::fixed outputs
@@ -956,7 +964,7 @@ namespace std
 
        _S_format_float(__io, __fbuf, __mod);
        __len = std::__convert_from_v(__cs, 0, __fbuf, __v, 
-                                     _S_c_locale, __prec);
+                                     _S_get_c_locale(), __prec);
 #endif
 
       // [22.2.2.2.2] Stage 2, convert to char_type, using correct
@@ -1124,7 +1132,7 @@ namespace std
       const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
       const _CharT* __wcs = __str.c_str();
       __ctype.narrow(__wcs, __wcs + __str.size() + 1, char(), __cs);      
-      std::__convert_to_v(__cs, __units, __err, _S_c_locale);
+      std::__convert_to_v(__cs, __units, __err, _S_get_c_locale());
       return __beg;
     }
 
@@ -1349,14 +1357,14 @@ namespace std
       int __cs_size = 64;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
       int __len = std::__convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
-                                       _S_c_locale);
+                                       _S_get_c_locale());
       // If the buffer was not large enough, try again with the correct size.
       if (__len >= __cs_size)
        {
          __cs_size = __len + 1;
          __cs = static_cast<char*>(__builtin_alloca(__cs_size));
          __len = std::__convert_from_v(__cs, __cs_size, "%.01Lf", __units, 
-                                       _S_c_locale);
+                                       _S_get_c_locale());
        }
 #else
       // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
@@ -1364,7 +1372,7 @@ namespace std
       const int __cs_size = numeric_limits<long double>::max_exponent10 + 5;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
       int __len = std::__convert_from_v(__cs, 0, "%.01Lf", __units, 
-                                       _S_c_locale);
+                                       _S_get_c_locale());
 #endif
       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 
                                                           * __cs_size));
@@ -1983,7 +1991,8 @@ namespace std
       if (__i == 2 || __i == 4)
        {
          long __l;
-         std::__convert_to_v(__digits.c_str(), __l, __err, _S_c_locale);
+         std::__convert_to_v(__digits.c_str(), __l, __err,
+                             _S_get_c_locale());
          if (!(__err & ios_base::failbit) && __l <= INT_MAX)
            {
              __l = __i == 2 ? __l : __l - 1900; 
index 08aa8b48032918bb7ecc5eda7b1114ca3f832721..82e13c6e5bc5934250ea2ba9bd4ada96fc3775ff 100644 (file)
@@ -46,7 +46,7 @@ namespace std
   codecvt<char, char, mbstate_t>::
   codecvt(size_t __refs)
   : __codecvt_abstract_base<char, char, mbstate_t>(__refs)
-  { _M_c_locale_codecvt = _S_c_locale; }
+  { _M_c_locale_codecvt = _S_get_c_locale(); }
 
   codecvt<char, char, mbstate_t>::
   codecvt(__c_locale __cloc, size_t __refs)
@@ -122,7 +122,7 @@ namespace std
   codecvt<wchar_t, char, mbstate_t>::
   codecvt(size_t __refs)
   : __codecvt_abstract_base<wchar_t, char, mbstate_t>(__refs)
-  { _M_c_locale_codecvt = _S_c_locale; }
+  { _M_c_locale_codecvt = _S_get_c_locale(); }
 
   codecvt<wchar_t, char, mbstate_t>::
   codecvt(__c_locale __cloc, size_t __refs)
index 5ddbd4137a88ebb13dd049ddc3c624672838f15d..1a84ced453a8fdd770a65fd02c23eb0d05751a09 100644 (file)
@@ -127,7 +127,7 @@ namespace std
 #ifdef _GLIBCXX_USE_WCHAR_T
   ctype<wchar_t>::ctype(size_t __refs) 
   : __ctype_abstract_base<wchar_t>(__refs)
-  { _M_c_locale_ctype = _S_c_locale; }
+  { _M_c_locale_ctype = _S_get_c_locale(); }
 
   ctype<wchar_t>::ctype(__c_locale __cloc, size_t __refs) 
   : __ctype_abstract_base<wchar_t>(__refs) 
index d1de4db6c1a5c87aa356c36b3d84ae48e3511e34..b37b30c43c26cb3bbfcdbea8e25b565385a84911 100644 (file)
@@ -60,10 +60,14 @@ namespace std
   // static data members of locale.
 
   // These are no longer exported.
-  locale::_Impl*               locale::_S_classic;
+  locale::_Impl*                locale::_S_classic;
   locale::_Impl*               locale::_S_global; 
   const size_t                         locale::_S_categories_size;
 
+#ifdef __GTHREADS
+  __gthread_once_t             locale::_S_once = __GTHREAD_ONCE_INIT;
+#endif
+
   // Definitions for static const data members of locale::id
   _Atomic_word locale::id::_S_highwater;  // init'd to 0 by linker
 
@@ -320,8 +324,9 @@ namespace std
   locale
   locale::global(const locale& __other)
   {
-    // XXX MT
     _S_initialize();
+
+    // XXX MT
     _Impl* __old = _S_global;
     __other._M_impl->_M_add_reference();
     _S_global = __other._M_impl; 
@@ -362,30 +367,31 @@ namespace std
   const locale&
   locale::classic()
   {
-    // Locking protocol: singleton-called-before-threading-starts
-    if (!_S_classic)
-      {
-       try 
-         {
-           // 26 Standard facets, 2 references.
-           // One reference for _S_classic, one for _S_global
-           _S_classic = new (&c_locale_impl) _Impl(0, 2, true);
-           _S_global = _S_classic;         
-           new (&c_locale) locale(_S_classic);
-         }
-       catch(...) 
-         {
-           // Just call destructor, so that locale_impl_c's memory is
-           // not deallocated via a call to delete.
-           if (_S_classic)
-             _S_classic->~_Impl();
-           _S_classic = _S_global = 0;
-           __throw_exception_again;
-         }
-      }
+    _S_initialize();
     return c_locale;
   }
 
+  void
+  locale::_S_initialize_once()
+  {
+    // 2 references.
+    // One reference for _S_classic, one for _S_global
+    _S_classic = new (&c_locale_impl) _Impl(2);
+    _S_global = _S_classic;        
+    new (&c_locale) locale(_S_classic);
+  }
+
+  void  
+  locale::_S_initialize()
+  {
+#ifdef __GTHREADS
+    __gthread_once(&_S_once, _S_initialize_once);
+#else
+    if (!_S_classic)
+      _S_initialize_once();
+#endif
+  }
+
   void
   locale::_M_coalesce(const locale& __base, const locale& __add, 
                      category __cat)
@@ -444,14 +450,36 @@ namespace std
     return __ret;
   }
 
-  __c_locale
-  locale::facet::_S_c_locale;
-  
-  char locale::facet::_S_c_name[2];
+  __c_locale locale::facet::_S_c_locale;
+
+  const char locale::facet::_S_c_name[2] = "C";
+
+#ifdef __GTHREADS
+  __gthread_once_t locale::facet::_S_once = __GTHREAD_ONCE_INIT;
+#endif
 
   locale::facet::
   ~facet() { }
 
+  void
+  locale::facet::_S_initialize_once()
+  {
+    // Initialize the underlying locale model.
+    _S_create_c_locale(_S_c_locale, _S_c_name);
+  }
+
+  __c_locale
+  locale::facet::_S_get_c_locale()
+  {
+#ifdef __GHTREADS
+    __gthread_once(&_S_once, _S_initialize_once);
+#else
+    if (!_S_c_locale)
+      _S_initialize_once();
+#endif
+    return _S_c_locale;
+  }
+
   // Definitions for static const data members of time_base.
   template<> 
     const char*
index 28e68b86416997055caf4c69ff7db0849eea0d4a..cb71e2fba9eb98879f12d52e91048d20be7c6bba 100644 (file)
@@ -245,15 +245,9 @@ namespace std
 
   // Construct "C" _Impl.
   locale::_Impl::
-  _Impl(facet**, size_t __refs, bool
+  _Impl(size_t __refs) throw(
   : _M_references(__refs), _M_facets_size(_GLIBCXX_NUM_FACETS)
   {
-    // Initialize the underlying locale model.
-    locale::facet::_S_c_name[0] = 'C';
-    locale::facet::_S_c_name[1] = '\0';
-    locale::facet::_S_create_c_locale(locale::facet::_S_c_locale, 
-                                     locale::facet::_S_c_name);
-
     _M_facets = new (&facet_vec) const facet*[_M_facets_size];
     _M_caches = new (&cache_vec) const facet*[_M_facets_size];
     for (size_t __i = 0; __i < _M_facets_size; ++__i)