aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2003-12-15 21:08:03 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2003-12-15 21:08:03 +0000
commit3fe1373814015056725f2de2faed739459023b91 (patch)
treef8e8ca945e453d4a8120f8e2e8418a21a57ad3c7
parent86d75cddd286af23fb680b5d12a7a3749a71d0d5 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in5
-rw-r--r--libstdc++-v3/include/bits/concurrence.h54
-rw-r--r--libstdc++-v3/src/locale_init.cc12
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