summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-11 20:18:36 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-11 20:18:36 +0000
commit198c4886b4c68cd8e86113c8a3cf2690bf10704d (patch)
treee2b3b8e33dd65cd353d4b4190f2cbe268011ec8e
parentae264e9a89c7ea71ab8153b4353b57189832129e (diff)
downloadgcc-198c4886b4c68cd8e86113c8a3cf2690bf10704d.tar.gz
2006-10-11 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/29426 * libsupc++/guard.cc (get_static_mutex): New. (mutex_wrapper::mutex_wrapper): Use it to get properly initialized recursive mutex without ordering issues. * src/locale_init.cc (__get_locale_mutex): No need to uglify. Change to get_locale_mutex. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117643 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog10
-rw-r--r--libstdc++-v3/libsupc++/guard.cc50
-rw-r--r--libstdc++-v3/src/locale_init.cc6
3 files changed, 44 insertions, 22 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 35d54f21146..edb15979bb2 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,13 @@
+2006-10-11 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/29426
+ * libsupc++/guard.cc (get_static_mutex): New.
+ (mutex_wrapper::mutex_wrapper): Use it to get properly initialized
+ recursive mutex without ordering issues.
+
+ * src/locale_init.cc (__get_locale_mutex): No need to
+ uglify. Change to get_locale_mutex.
+
2006-10-11 Paolo Carlini <pcarlini@suse.de>
* testsuite/22_locale/num_put/put/char/11.cc: New.
diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc
index a56fe15e7ee..eb6421689b3 100644
--- a/libstdc++-v3/libsupc++/guard.cc
+++ b/libstdc++-v3/libsupc++/guard.cc
@@ -32,6 +32,7 @@
#include <bits/c++config.h>
#include <cxxabi.h>
#include <exception>
+#include <new>
#include <ext/atomicity.h>
#include <ext/concurrence.h>
@@ -43,7 +44,22 @@
namespace
{
// A single mutex controlling all static initializations.
- __gnu_cxx::__recursive_mutex static_mutex;
+ static __gnu_cxx::__recursive_mutex* static_mutex;
+
+ typedef char fake_recursive_mutex[sizeof(__gnu_cxx::__recursive_mutex)]
+ __attribute__ ((aligned(__alignof__(__gnu_cxx::__recursive_mutex))));
+ fake_recursive_mutex fake_mutex;
+
+ static void init()
+ { static_mutex = new (&fake_mutex) __gnu_cxx::__recursive_mutex(); }
+
+ __gnu_cxx::__recursive_mutex&
+ get_static_mutex()
+ {
+ static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ __gthread_once(&once, init);
+ return *static_mutex;
+ }
}
#ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
@@ -98,18 +114,14 @@ namespace __cxxabiv1
{
static inline int
recursion_push (__guard* g)
- {
- return ((char *)g)[1]++;
- }
+ { return ((char *)g)[1]++; }
static inline void
recursion_pop (__guard* g)
- {
- --((char *)g)[1];
- }
+ { --((char *)g)[1]; }
static int
- acquire_1 (__guard *g)
+ acquire (__guard *g)
{
if (_GLIBCXX_GUARD_TEST (g))
return 0;
@@ -142,18 +154,18 @@ namespace __cxxabiv1
struct mutex_wrapper
{
bool unlock;
- mutex_wrapper (): unlock(true)
- {
- static_mutex.lock();
- }
- ~mutex_wrapper ()
+ mutex_wrapper() : unlock(true)
+ { get_static_mutex().lock(); }
+
+ ~mutex_wrapper()
{
if (unlock)
- static_mutex.unlock();
+ static_mutex->unlock();
}
- } mw;
+ };
- if (acquire_1 (g))
+ mutex_wrapper mw;
+ if (acquire (g))
{
mw.unlock = false;
return 1;
@@ -163,7 +175,7 @@ namespace __cxxabiv1
}
#endif
- return acquire_1 (g);
+ return acquire (g);
}
extern "C"
@@ -172,7 +184,7 @@ namespace __cxxabiv1
recursion_pop (g);
#ifdef __GTHREADS
if (__gthread_active_p ())
- static_mutex.unlock();
+ static_mutex->unlock();
#endif
}
@@ -183,7 +195,7 @@ namespace __cxxabiv1
_GLIBCXX_GUARD_SET_AND_RELEASE (g);
#ifdef __GTHREADS
if (__gthread_active_p ())
- static_mutex.unlock();
+ static_mutex->unlock();
#endif
}
}
diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc
index a2c18dd84cb..28ee484112f 100644
--- a/libstdc++-v3/src/locale_init.cc
+++ b/libstdc++-v3/src/locale_init.cc
@@ -37,7 +37,7 @@
namespace
{
__gnu_cxx::__mutex&
- __get_locale_mutex()
+ get_locale_mutex()
{
static __gnu_cxx::__mutex locale_mutex;
return locale_mutex;
@@ -212,7 +212,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
locale::locale() throw() : _M_impl(0)
{
_S_initialize();
- __gnu_cxx::__scoped_lock sentry(__get_locale_mutex());
+ __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
_S_global->_M_add_reference();
_M_impl = _S_global;
}
@@ -223,7 +223,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_S_initialize();
_Impl* __old;
{
- __gnu_cxx::__scoped_lock sentry(__get_locale_mutex());
+ __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
__old = _S_global;
__other._M_impl->_M_add_reference();
_S_global = __other._M_impl;