re PR libstdc++/12658 (Thread safety problems in locale::global() and locale::locale())
authorBenjamin Kosnik <bkoz@redhat.com>
Sun, 7 Mar 2004 01:32:43 +0000 (01:32 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Sun, 7 Mar 2004 01:32:43 +0000 (01:32 +0000)
2004-03-06  Benjamin Kosnik  <bkoz@redhat.com>

PR libstdc++/12658
* src/locale_init.cc (locale::locale): Lock critical regions with
external mutexes.
(locale::global): Same.
* include/bits/concurrence.h (__glibcxx_mutex_define_initialized):
Add in once bits for cases without __GTHREAD_MUTEX_INIT.
(__glibcxx_mutex_lock): Same.

* config/cpu/generic/atomicity.h: Remove
_GLIBCXX_NEED_GENERIC_MUTEX, use concurrence.h.
* src/misc-inst.cc: Move all locking bits out of this file.

* config/os/hpux/os_defines.h: Remove _GLIBCXX_INST_ATOMICITY_LOCK.
* src/misc-inst.cc: Same.
* config/cpu/hppa/atomicity.h: Same.

* config/linker-map.gnu: Remove types in the signature of atomic
exports, as they may vary.

From-SVN: r79043

libstdc++-v3/ChangeLog
libstdc++-v3/config/cpu/generic/atomicity.h
libstdc++-v3/config/cpu/hppa/atomicity.h
libstdc++-v3/config/linker-map.gnu
libstdc++-v3/config/os/hpux/os_defines.h
libstdc++-v3/include/bits/concurrence.h
libstdc++-v3/include/ext/mt_allocator.h
libstdc++-v3/src/locale_init.cc
libstdc++-v3/src/misc-inst.cc

index e146e484ca9924b8e42d78130882a68868f6cebd..2f36a46b46167150a2d16c4f17cd347c04a34e1f 100644 (file)
@@ -1,3 +1,24 @@
+2004-03-06  Benjamin Kosnik  <bkoz@redhat.com>
+
+       PR libstdc++/12658
+       * src/locale_init.cc (locale::locale): Lock critical regions with
+       external mutexes.
+       (locale::global): Same. 
+       * include/bits/concurrence.h (__glibcxx_mutex_define_initialized): 
+       Add in once bits for cases without __GTHREAD_MUTEX_INIT.
+       (__glibcxx_mutex_lock): Same.
+
+       * config/cpu/generic/atomicity.h: Remove
+       _GLIBCXX_NEED_GENERIC_MUTEX, use concurrence.h.
+       * src/misc-inst.cc: Move all locking bits out of this file.
+
+       * config/os/hpux/os_defines.h: Remove _GLIBCXX_INST_ATOMICITY_LOCK.
+       * src/misc-inst.cc: Same.
+       * config/cpu/hppa/atomicity.h: Same.
+
+       * config/linker-map.gnu: Remove types in the signature of atomic
+       exports, as they may vary.
+       
 2004-03-06  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/locale_facets.tcc: Tweak the comment preceding
index 84817903bf5f7501f302b6b533a21100aa2bd397..f30005a0abce67d9de617b3d7b5e9b5a8df11750 100644 (file)
 // the GNU General Public License.
 
 #include <bits/atomicity.h>
-#include <bits/gthr.h>
+#include <bits/concurrence.h>
 
-#define _GLIBCXX_NEED_GENERIC_MUTEX
+namespace __gnu_internal
+{
+  __glibcxx_mutex_define_initialized(atomic_mutex);
+} // namespace __gnu_internal
 
 namespace __gnu_cxx
 {
-  extern __gthread_mutex_t _Atomic_add_mutex;
-
-#ifndef __GTHREAD_MUTEX_INIT
-  extern __gthread_once_t _Atomic_add_mutex_once;
-  extern void __gthread_atomic_add_mutex_once();
-#endif
-
   _Atomic_word
   __attribute__ ((__unused__))
   __exchange_and_add(volatile _Atomic_word* __mem, int __val)
   {
-#ifndef __GTHREAD_MUTEX_INIT
-    __gthread_once(&__gnu_cxx::_Atomic_add_mutex_once,
-                  __gnu_cxx::__gthread_atomic_add_mutex_once);
-#endif
-
+    __glibcxx_mutex_lock(__gnu_internal::atomic_mutex);
     _Atomic_word __result;
-    __gthread_mutex_lock(&__gnu_cxx::_Atomic_add_mutex);
     __result = *__mem;
     *__mem += __val;
-
-    __gthread_mutex_unlock(&__gnu_cxx::_Atomic_add_mutex);
+    __glibcxx_mutex_unlock(__gnu_internal::atomic_mutex);
     return __result;
   }
 
index d173976e68e5d5095e893816083c33f45624d8fe..48c8283a544652c8f806797873d9be889edcd124 100644 (file)
@@ -43,11 +43,8 @@ namespace __gnu_cxx
   _Atomicity_lock<_Inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1;
 
   // Because of the lack of weak support when using the hpux som
-  // linker, we explicitly instantiate the atomicity lock in
-  // src/misc-inst.cc when _GLIBCXX_INST_ATOMICITY_LOCK is defined.
-#ifndef _GLIBCXX_INST_ATOMICITY_LOCK
+  // linker, we explicitly instantiate the atomicity lock.
   template volatile int _Atomicity_lock<0>::_S_atomicity_lock;
-#endif
 
   int
   __attribute__ ((__unused__))
index c8be24240702c3d1546558bb85cc26e84ad99700..7dd9a2a12f79b58102004e0e5d0cf5719d61da75 100644 (file)
@@ -216,8 +216,8 @@ GLIBCXX_3.4 {
 
     # __gnu_cxx::__atomic_add
     # __gnu_cxx::__exchange_and_add
-    _ZN9__gnu_cxx12__atomic_addEPVii;
-    _ZN9__gnu_cxx18__exchange_and_addEPVii;
+    _ZN9__gnu_cxx12__atomic_add*;
+    _ZN9__gnu_cxx18__exchange_and_add*;
 
   # DO NOT DELETE THIS LINE.  Port-specific symbols, if any, will be here.
 
index 64962fedb1c9a4af5da803955b998786a81d0b8d..6cba7390f388aebcab16a4cff39fe0d592915c91 100644 (file)
@@ -91,12 +91,6 @@ typedef long int __padding_type;
 #define _LIBUNWIND_STD_ABI 1
 #endif
 
-/* We need explicit instantiation of the atomicity lock on HPPA if
-   there is no weak support.  */
-#if !__GXX_WEAK__ && defined (__hppa__)
-#define _GLIBCXX_INST_ATOMICITY_LOCK 1
-#endif
-
 /* Don't use pragma weak in gthread headers.  HP-UX rejects programs
    with unsatisfied external references even if all of those references
    are weak; gthread relies on such unsatisfied references being resolved
index fe67881c76bab0bcd0360d27216b24b54732d0be..ea99e56e7efd2ca8accd74cf930cc9ed7f9cdb79 100644 (file)
@@ -1,6 +1,6 @@
 // Support for concurrent programing -*- C++ -*-
 
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
-#ifndef _CONCURRENCE
-#define _CONCURRENCE 1
+#ifndef _CONCURRENCE_H
+#define _CONCURRENCE_H 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
+#  define __glibcxx_mutex_lock(NAME) \
+__gthread_mutex_lock(&NAME)
 # else
+// Implies __GTHREAD_MUTEX_INIT_FUNCTION
 #  define __glibcxx_mutex_define_initialized(NAME) \
 __gthread_mutex_t NAME; \
-__GTHREAD_MUTEX_INIT_FUNCTION(&NAME)
+__gthread_once_t NAME ## _once = __GTHREAD_ONCE_INIT; \
+void NAME ## _init() { __GTHREAD_MUTEX_INIT_FUNCTION(&NAME); }
+# define __glibcxx_mutex_lock(NAME) \
+__gthread_once(&NAME ## _once, NAME ## _init); \
+__gthread_mutex_lock(&NAME)
 # endif
-# define __glibcxx_mutex_lock(LOCK) __gthread_mutex_lock(&LOCK)
-# define __glibcxx_mutex_unlock(LOCK) __gthread_mutex_unlock(&LOCK)
+
+# define __glibcxx_mutex_unlock(NAME) __gthread_mutex_unlock(&NAME)
+
 #else
+
 # define __glibcxx_mutex_define_initialized(NAME)
-# define __glibcxx_mutex_lock(LOCK)
-# define __glibcxx_mutex_unlock(LOCK)
+# define __glibcxx_mutex_lock(NAME)
+# define __glibcxx_mutex_unlock(NAME)
+
 #endif
 
 #endif
index 7000c05fe0b72346ca33b8e84fec1f7c81499ad2..1bcff03356dceb580d462b29eee7549f967f523c 100644 (file)
@@ -559,8 +559,8 @@ namespace __gnu_cxx
        }
 
       // Setup the bin map for quick lookup of the relevant bin.
-      _S_binmap = (binmap_type*)
-        ::operator new ((_S_options._M_max_bytes + 1) * sizeof(binmap_type));
+      const size_t n1 = (_S_options._M_max_bytes + 1) * sizeof(binmap_type);
+      _S_binmap = static_cast<binmap_type*>(::operator new(n1));
 
       binmap_type* bp_t = _S_binmap;
       binmap_type bin_max_t = 1;
@@ -581,9 +581,8 @@ namespace __gnu_cxx
 #ifdef __GTHREADS
       if (__gthread_active_p())
         {
-          _S_thread_freelist_first =
-            static_cast<thread_record*>(::operator 
-              new(sizeof(thread_record) * _S_options._M_max_threads));
+         const size_t n2 = sizeof(thread_record) * _S_options._M_max_threads;
+          _S_thread_freelist_first = static_cast<thread_record*>(::operator new(n2));
 
          // NOTE! The first assignable thread id is 1 since the
          // global pool uses id 0
@@ -637,7 +636,7 @@ namespace __gnu_cxx
                 *br.mutex = __tmp;
               }
 #else
-              { __GTHREAD_MUTEX_INIT_FUNCTION (br.mutex); }
+              { __GTHREAD_MUTEX_INIT_FUNCTION(br.mutex); }
 #endif
             }
 #endif
@@ -741,12 +740,13 @@ namespace __gnu_cxx
   template<typename _Tp> 
     __gthread_key_t __mt_alloc<_Tp>::_S_thread_key;
 
-  template<typename _Tp> __gthread_mutex_t
+  template<typename _Tp> 
+    __gthread_mutex_t
 #ifdef __GTHREAD_MUTEX_INIT
-  __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
+    __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
 #else
   // XXX
-  __mt_alloc<_Tp>::_S_thread_freelist_mutex;
+    __mt_alloc<_Tp>::_S_thread_freelist_mutex;
 #endif
 #endif
 } // namespace __gnu_cxx
index 78f91d24887d0fdc751103020d4567356f9fb2b0..c1dac9f7a7c22e7ec028902f670984dcc0e3a4b5 100644 (file)
@@ -88,6 +88,10 @@ namespace __gnu_internal
   extern std::__moneypunct_cache<wchar_t, true>         moneypunct_cache_wt;
   extern std::__timepunct_cache<wchar_t>        timepunct_cache_w;
 #endif
+
+  // Mutex objects for locale initialization.
+  __glibcxx_mutex_define_initialized(locale_cons_mutex);
+  __glibcxx_mutex_define_initialized(locale_global_mutex);
 } // namespace __gnu_internal
 
 namespace std 
@@ -97,19 +101,23 @@ namespace std
   locale::locale() throw()
   { 
     _S_initialize(); 
+    __glibcxx_mutex_lock(__gnu_internal::locale_cons_mutex);
     _S_global->_M_add_reference();
     _M_impl = _S_global;
+    __glibcxx_mutex_unlock(__gnu_internal::locale_cons_mutex);
   }
 
   locale
   locale::global(const locale& __other)
   {
     _S_initialize();
+    __glibcxx_mutex_lock(__gnu_internal::locale_global_mutex);
     _Impl* __old = _S_global;
     __other._M_impl->_M_add_reference();
     _S_global = __other._M_impl; 
     if (__other.name() != "*")
       setlocale(LC_ALL, __other.name().c_str());
+   __glibcxx_mutex_unlock(__gnu_internal::locale_global_mutex);
 
     // Reference count sanity check: one reference removed for the
     // subsition of __other locale, one added by return-by-value. Net
index c44965259287da257c1fdff7734908453c425b6c..b9bc29882f09fe89ae5f642a41aaaa91275d6fe3 100644 (file)
@@ -73,24 +73,6 @@ namespace std
 
 namespace __gnu_cxx
 {
-#ifdef _GLIBCXX_INST_ATOMICITY_LOCK
-  template volatile int _Atomicity_lock<0>::_S_atomicity_lock;
-#endif
-
-#ifdef _GLIBCXX_NEED_GENERIC_MUTEX
-#ifdef __GTHREAD_MUTEX_INIT
-  __gthread_mutex_t _Atomic_add_mutex = __GTHREAD_MUTEX_INIT;
-#else
-  // generic atomicity.h without static initialization
-  __gthread_mutex_t _Atomic_add_mutex;
-  __gthread_once_t _Atomic_add_mutex_once = __GTHREAD_ONCE_INIT;
-  void __gthread_atomic_add_mutex_once()
-  {
-    __GTHREAD_MUTEX_INIT_FUNCTION (&_Atomic_add_mutex);
-  }
-#endif
-#endif // _GLIBCXX_NEED_GLOBAL_MUTEX
-
   template class stdio_sync_filebuf<char>;
 #ifdef _GLIBCXX_USE_WCHAR_T
   template class stdio_sync_filebuf<wchar_t>;