mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 16:37:23 +08:00
re PR libstdc++/12658 (Thread safety problems in locale::global() and locale::locale())
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
This commit is contained in:
parent
018e1b3b0b
commit
f83295bafc
@ -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
|
||||
|
@ -28,34 +28,24 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -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__))
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -28,27 +28,38 @@
|
||||
// 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
Loading…
Reference in New Issue
Block a user