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:
Benjamin Kosnik 2004-03-07 01:32:43 +00:00 committed by Benjamin Kosnik
parent 018e1b3b0b
commit f83295bafc
9 changed files with 67 additions and 64 deletions

View 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

View File

@ -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;
}

View 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__))

View 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.

View 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

View 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
@ -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

View 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

View 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

View 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>;