diff options
author | Benjamin Kosnik <bkoz@redhat.com> | 2003-12-15 21:08:03 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-12-15 21:08:03 +0000 |
commit | 3fe1373814015056725f2de2faed739459023b91 (patch) | |
tree | f8e8ca945e453d4a8120f8e2e8418a21a57ad3c7 | |
parent | 86d75cddd286af23fb680b5d12a7a3749a71d0d5 (diff) | |
download | gcc-3fe1373814015056725f2de2faed739459023b91.zip gcc-3fe1373814015056725f2de2faed739459023b91.tar.gz gcc-3fe1373814015056725f2de2faed739459023b91.tar.bz2 |
re PR libstdc++/12658 (Thread safety problems in locale::global() and locale::locale())
2003-12-15 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/12658
* include/Makefile.am (bits_headers): Add concurrence.h.
* include/Makefile.in: Regenerated.
* include/bits/concurrence.h: New.
* src/locale_init.cc: Use it.
(locale::locale): Lock critical regions.
(locale::global): Same.
From-SVN: r74648
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/concurrence.h | 54 | ||||
-rw-r--r-- | libstdc++-v3/src/locale_init.cc | 12 |
5 files changed, 77 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index fc10ab7..70805f5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2003-12-15 Benjamin Kosnik <bkoz@redhat.com> + PR libstdc++/12658 + * include/Makefile.am (bits_headers): Add concurrence.h. + * include/Makefile.in: Regenerated. + * include/bits/concurrence.h: New. + * src/locale_init.cc: Use it. + (locale::locale): Lock critical regions. + (locale::global): Same. + +2003-12-15 Benjamin Kosnik <bkoz@redhat.com> + * include/bits/basic_string.h: Change _*_references to _*_refcount. * include/bits/locale_classes.h: Same. * src/locale.cc: Same. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 3af38b3..b97267b 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -101,6 +101,7 @@ bits_headers = \ ${bits_srcdir}/char_traits.h \ ${bits_srcdir}/codecvt.h \ ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/concurrence.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/demangle.h \ ${bits_srcdir}/deque.tcc \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 8fdc4c0..0ba5afb 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -296,6 +296,7 @@ bits_headers = \ ${bits_srcdir}/char_traits.h \ ${bits_srcdir}/codecvt.h \ ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/concurrence.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/demangle.h \ ${bits_srcdir}/deque.tcc \ @@ -518,15 +519,15 @@ debug_headers = \ ${debug_srcdir}/string \ ${debug_srcdir}/vector +@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = # Some of the different "C" header models need extra files. # Some "C" header schemes require the "C" compatibility headers. # For --enable-cheaders=c_std @GLIBCXX_C_HEADERS_C_STD_TRUE@c_base_headers_extra = ${c_base_srcdir}/cmath.tcc -@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = -@GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers} +@GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) host_builddir = ./${host_alias}/bits diff --git a/libstdc++-v3/include/bits/concurrence.h b/libstdc++-v3/include/bits/concurrence.h new file mode 100644 index 0000000..68b9ab7 --- /dev/null +++ b/libstdc++-v3/include/bits/concurrence.h @@ -0,0 +1,54 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CONCURRENCE +#define _CONCURRENCE 1 + +// GCC's thread abstraction layer +#include "bits/gthr.h" + +#if __GTHREADS +# ifdef __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_define_initialized(NAME) \ +__gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT +# else +# define __glibcxx_mutex_define_initialized(NAME) \ +__gthread_mutex_t NAME; \ +__GTHREAD_MUTEX_INIT_FUNCTION(&NAME) +# endif +# define __glibcxx_mutex_lock(LOCK) __gthread_mutex_lock(&LOCK) +# define __glibcxx_mutex_unlock(LOCK) __gthread_mutex_unlock(&LOCK) +#else +# define __glibcxx_mutex_define_initialized(NAME) +# define __glibcxx_mutex_lock(LOCK) +# define __glibcxx_mutex_unlock(LOCK) +#endif + +#endif diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc index a71bb5d..2fd22f6 100644 --- a/libstdc++-v3/src/locale_init.cc +++ b/libstdc++-v3/src/locale_init.cc @@ -33,6 +33,7 @@ #include <cwctype> // For towupper, etc. #include <locale> #include <bits/atomicity.h> +#include <bits/concurrence.h> namespace __gnu_cxx { @@ -96,21 +97,26 @@ namespace std locale::locale() throw() { _S_initialize(); - (_M_impl = _S_global)->_M_add_reference(); + __glibcxx_mutex_define_initialized(lock); + __glibcxx_mutex_lock(lock); + _S_global->_M_add_reference(); + _M_impl = _S_global; + __glibcxx_mutex_unlock(lock); } locale locale::global(const locale& __other) { _S_initialize(); - - // XXX MT + __glibcxx_mutex_define_initialized(lock); + __glibcxx_mutex_lock(lock); _Impl* __old = _S_global; __other._M_impl->_M_add_reference(); _S_global = __other._M_impl; if (_S_global->_M_check_same_name() && (std::strcmp(_S_global->_M_names[0], "*") != 0)) setlocale(LC_ALL, __other.name().c_str()); + __glibcxx_mutex_unlock(lock); // Reference count sanity check: one reference removed for the // subsition of __other locale, one added by return-by-value. Net |