diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9abb29f0fd4..59b6bffa2da 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,59 @@ +2003-10-02 Benjamin Kosnik + + * config/linker-map.gnu: Export _S_get_c_locale instead of + _S_c_locale object. + +2003-10-02 Petur Runolfsson + + * 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::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 * include/bits/demangle.h (demangle::symbol(char const*)): diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu index fa54dcf1a05..d0ab03c191d 100644 --- a/libstdc++-v3/config/linker-map.gnu +++ b/libstdc++-v3/config/linker-map.gnu @@ -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*; diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc index 5a211a187df..a9d9537ffdb 100644 --- a/libstdc++-v3/config/locale/generic/c_locale.cc +++ b/libstdc++-v3/config/locale/generic/c_locale.cc @@ -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 diff --git a/libstdc++-v3/config/locale/generic/messages_members.h b/libstdc++-v3/config/locale/generic/messages_members.h index 2d588049c4f..3e9122e880f 100644 --- a/libstdc++-v3/config/locale/generic/messages_members.h +++ b/libstdc++-v3/config/locale/generic/messages_members.h @@ -37,12 +37,12 @@ template messages<_CharT>::messages(size_t __refs) : facet(__refs) - { _M_c_locale_messages = _S_c_locale; } + { _M_c_locale_messages = _S_get_c_locale(); } template 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 messages<_CharT>::catalog diff --git a/libstdc++-v3/config/locale/generic/time_members.h b/libstdc++-v3/config/locale/generic/time_members.h index 8db2cb53ed8..2da37eb95b3 100644 --- a/libstdc++-v3/config/locale/generic/time_members.h +++ b/libstdc++-v3/config/locale/generic/time_members.h @@ -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); } diff --git a/libstdc++-v3/config/locale/gnu/c_locale.cc b/libstdc++-v3/config/locale/gnu/c_locale.cc index 1309c0308eb..3c7d258e875 100644 --- a/libstdc++-v3/config/locale/gnu/c_locale.cc +++ b/libstdc++-v3/config/locale/gnu/c_locale.cc @@ -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 diff --git a/libstdc++-v3/config/locale/gnu/messages_members.h b/libstdc++-v3/config/locale/gnu/messages_members.h index 48dcf32dd2e..fc2bb2eceb5 100644 --- a/libstdc++-v3/config/locale/gnu/messages_members.h +++ b/libstdc++-v3/config/locale/gnu/messages_members.h @@ -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 @@ -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); } @@ -101,8 +102,9 @@ #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); diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc index 36e2365f664..d97f0dc6f50 100644 --- a/libstdc++-v3/config/locale/gnu/numeric_members.cc +++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc @@ -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; diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc b/libstdc++-v3/config/locale/gnu/time_members.cc index e49b66b256f..62dc843dfd7 100644 --- a/libstdc++-v3/config/locale/gnu/time_members.cc +++ b/libstdc++-v3/config/locale/gnu/time_members.cc @@ -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"; diff --git a/libstdc++-v3/config/locale/gnu/time_members.h b/libstdc++-v3/config/locale/gnu/time_members.h index 6badaacbfa0..3129cd17694 100644 --- a/libstdc++-v3/config/locale/gnu/time_members.h +++ b/libstdc++-v3/config/locale/gnu/time_members.h @@ -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); } diff --git a/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h b/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h index 01ef01f4065..83a93cb9dfe 100644 --- a/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h +++ b/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h @@ -37,10 +37,7 @@ #if _GLIBCXX_C_LOCALE_GNU const ctype_base::mask* ctype::classic_table() throw() - { - locale::classic(); - return _S_c_locale->__ctype_b; - } + { return _S_get_c_locale()->__ctype_b; } #else const ctype_base::mask* ctype::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::ctype(const mask* __table, bool __del, size_t __refs) : __ctype_abstract_base(__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; @@ -117,7 +114,7 @@ #endif setlocale(LC_CTYPE, __old); free(__old); - _M_c_locale_ctype = _S_c_locale; + _M_c_locale_ctype = _S_get_c_locale(); } #endif diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h index f013142ffea..1d123a93c64 100644 --- a/libstdc++-v3/include/bits/codecvt.h +++ b/libstdc++-v3/include/bits/codecvt.h @@ -341,8 +341,7 @@ 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); } diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h index 5ecbf7d6516..d9502bd2ae0 100644 --- a/libstdc++-v3/include/bits/locale_classes.h +++ b/libstdc++-v3/include/bits/locale_classes.h @@ -46,6 +46,7 @@ #include // For strcmp. #include #include +#include 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(); diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 234a0cf269e..96fc3a0da35 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -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; diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index cbfed442c8d..ad5c59bf9b4 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -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::max()) __v = static_cast(__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::max()) __v = static_cast(__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(__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(__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 >(__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(__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(__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::max_exponent10 + 5; char* __cs = static_cast(__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; diff --git a/libstdc++-v3/src/codecvt.cc b/libstdc++-v3/src/codecvt.cc index 08aa8b48032..82e13c6e5bc 100644 --- a/libstdc++-v3/src/codecvt.cc +++ b/libstdc++-v3/src/codecvt.cc @@ -46,7 +46,7 @@ namespace std codecvt:: codecvt(size_t __refs) : __codecvt_abstract_base(__refs) - { _M_c_locale_codecvt = _S_c_locale; } + { _M_c_locale_codecvt = _S_get_c_locale(); } codecvt:: codecvt(__c_locale __cloc, size_t __refs) @@ -122,7 +122,7 @@ namespace std codecvt:: codecvt(size_t __refs) : __codecvt_abstract_base(__refs) - { _M_c_locale_codecvt = _S_c_locale; } + { _M_c_locale_codecvt = _S_get_c_locale(); } codecvt:: codecvt(__c_locale __cloc, size_t __refs) diff --git a/libstdc++-v3/src/ctype.cc b/libstdc++-v3/src/ctype.cc index 5ddbd4137a8..1a84ced453a 100644 --- a/libstdc++-v3/src/ctype.cc +++ b/libstdc++-v3/src/ctype.cc @@ -127,7 +127,7 @@ namespace std #ifdef _GLIBCXX_USE_WCHAR_T ctype::ctype(size_t __refs) : __ctype_abstract_base(__refs) - { _M_c_locale_ctype = _S_c_locale; } + { _M_c_locale_ctype = _S_get_c_locale(); } ctype::ctype(__c_locale __cloc, size_t __refs) : __ctype_abstract_base(__refs) diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index d1de4db6c1a..b37b30c43c2 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -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* diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index 28e68b86416..cb71e2fba9e 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -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)