diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index bf13f595b5a..c581a496e88 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,29 @@ +2006-11-11 Paolo Carlini + + PR libstdc++/29496 + * include/debug/safe_base.h (_Safe_sequence_base::_M_get_mutex, + _Safe_iterator_base::_M_get_mutex, _M_attach_single, _M_detach_single): + New. + * src/debug.cc: Define the latter. + (_Safe_sequence_base::_M_detach_all, _M_detach_singular, + _M_revalidate_singular, _M_swap): Use the mutex. + (_Safe_iterator_base::_M_attach, _M_detach): Adjust, forward to the + *_single version. + * include/debug/safe_iterator.h (_Safe_iterator<>::_M_attach_single, + _M_invalidate_single): New. + * include/debug/safe_iterator.tcc: Define. + (_Safe_iterator<>::_M_invalidate): Adjust, forward to + _M_invalidate_single. + * include/debug/safe_sequence.h (_Safe_sequence<>::_M_invalidate_if, + _M_transfer_iter): Use the mutex, adjust, forward to the *_single + versions of _M_invalidate and _M_attach. + * config/abi/pre/gnu.ver (_Safe_sequence_base::_M_get_mutex, + _Safe_iterator_base::_M_get_mutex, _M_attach_single, _M_detach_single): + Add @GLIBCXX_3.4.10; adjust. + * configure.ac (libtool_VERSION): To 6:10:0. + * testsuite/util/testsuite_abi.cc (check_version): Add GLIBCXX_3.4.10. + * configure: Regenerate. + 2006-11-10 Jakub Jelinek * config/locale/gnu/c_locale.cc (__convert_to_v): Prefer diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index dd6854c80f7..327222d1e7d 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -120,13 +120,21 @@ GLIBCXX_3.4 { std::__moneypunct_cache*; std::__numpunct_cache*; std::__timepunct_cache*; - __gnu_debug::_Safe_iterator_base*; - __gnu_debug::_Safe_sequence_base*; __gnu_debug::_Error_formatter* }; # Names not in an 'extern' block are mangled names. + # __gnu_debug::_Safe_sequence_base and _Safe_iterator_base + _ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv; + _ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv; + _ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv; + _ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_; + _ZN11__gnu_debug19_Safe_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb; + _ZN11__gnu_debug19_Safe_iterator_base9_M_detachEv; + _ZNK11__gnu_debug19_Safe_iterator_base11_M_singularEv; + _ZNK11__gnu_debug19_Safe_iterator_base14_M_can_compareERKS0_; + # std::string _ZNSsC*; _ZNSsD*; @@ -662,8 +670,17 @@ GLIBCXX_3.4.9 { _ZNSo9_M_insertEPKc[il]; _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertEPKw[il]; + } GLIBCXX_3.4.8; +GLIBCXX_3.4.10 { + + _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv; + _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb; + _ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv; + _ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv; + +} GLIBCXX_3.4.9; # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 2de31fea740..ae9283da151 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -1378,7 +1378,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:9:0 +libtool_VERSION=6:10:0 # Find the rest of the source tree framework. diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 6c00c6b9a2c..b3f17dd5d4e 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -12,7 +12,7 @@ AC_CONFIG_HEADER(config.h) ### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:9:0 +libtool_VERSION=6:10:0 AC_SUBST(libtool_VERSION) # Find the rest of the source tree framework. diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h index 8640497d424..2851fc3fa9c 100644 --- a/libstdc++-v3/include/debug/safe_base.h +++ b/libstdc++-v3/include/debug/safe_base.h @@ -31,6 +31,8 @@ #ifndef _GLIBCXX_DEBUG_SAFE_BASE_H #define _GLIBCXX_DEBUG_SAFE_BASE_H 1 +#include + namespace __gnu_debug { class _Safe_sequence_base; @@ -103,6 +105,9 @@ namespace __gnu_debug ~_Safe_iterator_base() { this->_M_detach(); } + /** For use in _Safe_iterator. */ + __gnu_cxx::__mutex& _M_get_mutex(); + public: /** Attaches this iterator to the given sequence, detaching it * from whatever sequence it was attached to originally. If the @@ -111,11 +116,17 @@ namespace __gnu_debug */ void _M_attach(_Safe_sequence_base* __seq, bool __constant); + /** Likewise, but not thread-safe. */ + void _M_attach_single(_Safe_sequence_base* __seq, bool __constant); + /** Detach the iterator for whatever sequence it is attached to, * if any. */ void _M_detach(); + /** Likewise, but not thread-safe. */ + void _M_detach_single(); + /** Determines if we are attached to the given sequence. */ bool _M_attached_to(const _Safe_sequence_base* __seq) const { return _M_sequence == __seq; } @@ -196,6 +207,9 @@ namespace __gnu_debug void _M_swap(_Safe_sequence_base& __x); + /** For use in _Safe_sequence. */ + __gnu_cxx::__mutex& _M_get_mutex(); + public: /** Invalidates all iterators. */ void diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index cd30bf70df1..0d61a75eec9 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -321,10 +321,22 @@ namespace __gnu_debug _M_constant()); } + /** Likewise, but not thread-safe. */ + void + _M_attach_single(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq), + _M_constant()); + } + /** Invalidate the iterator, making it singular. */ void _M_invalidate(); + /** Likewise, but not thread-safe. */ + void + _M_invalidate_single(); + /// Is the iterator dereferenceable? bool _M_dereferenceable() const diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index ac9a09a2e83..08b629e8916 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -110,24 +110,33 @@ namespace __gnu_debug void _Safe_iterator<_Iterator, _Sequence>:: _M_invalidate() + { + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + _M_invalidate_single(); + } + + template + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate_single() { typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; if (!this->_M_singular()) { - for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter;) + for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators; + __iter; __iter = __iter->_M_next) { - iterator* __victim = static_cast(iter); - iter = iter->_M_next; + iterator* __victim = static_cast(__iter); if (this->base() == __victim->base()) __victim->_M_version = 0; } - for (_Safe_iterator_base* iter = _M_sequence->_M_const_iterators; - iter;) + + for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators; + __iter2; __iter2 = __iter2->_M_next) { - const_iterator* __victim = static_cast(iter); - iter = iter->_M_next; + const_iterator* __victim = static_cast(__iter2); if (__victim->base() == this->base()) __victim->_M_version = 0; } diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h index 36c7e42cd56..fe356aa53ea 100644 --- a/libstdc++-v3/include/debug/safe_sequence.h +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -124,27 +124,28 @@ namespace __gnu_debug typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; - for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) - { - iterator* __victim = static_cast(__iter); - __iter = __iter->_M_next; - if (!__victim->_M_singular()) - { - if (__pred(__victim->base())) - __victim->_M_invalidate(); - } - } + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + for (_Safe_iterator_base* __iter = _M_iterators; __iter;) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate_single(); + } + } - for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) - { - const_iterator* __victim = static_cast(__iter2); - __iter2 = __iter2->_M_next; - if (!__victim->_M_singular()) - { - if (__pred(__victim->base())) - __victim->_M_invalidate(); - } - } + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate_single(); + } + } } template @@ -160,22 +161,23 @@ namespace __gnu_debug typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; - for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; ) - { - iterator* __victim = static_cast(__iter); - __iter = __iter->_M_next; - if (!__victim->_M_singular() && __victim->base() == __x.base()) - __victim->_M_attach(static_cast<_Sequence*>(this)); - } + __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter;) + { + iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach_single(static_cast<_Sequence*>(this)); + } for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; __iter2;) - { - const_iterator* __victim = static_cast(__iter2); - __iter2 = __iter2->_M_next; - if (!__victim->_M_singular() && __victim->base() == __x.base()) - __victim->_M_attach(static_cast<_Sequence*>(this)); - } + { + const_iterator* __victim = static_cast(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach_single(static_cast<_Sequence*>(this)); + } } } // namespace __gnu_debug diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc index 46c6c14810f..d3935842be9 100644 --- a/libstdc++-v3/src/debug.cc +++ b/libstdc++-v3/src/debug.cc @@ -35,13 +35,12 @@ #include #include #include -#include using namespace std; namespace { - __gnu_cxx::__mutex iterator_base_mutex; + __gnu_cxx::__mutex safe_base_mutex; } // anonymous namespace namespace __gnu_debug @@ -107,43 +106,45 @@ namespace __gnu_debug "attempt to increment an end-of-stream istreambuf_iterator" }; - void + void _Safe_sequence_base:: _M_detach_all() { - for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); + for (_Safe_iterator_base* __iter = _M_iterators; __iter;) { _Safe_iterator_base* __old = __iter; __iter = __iter->_M_next; - __old->_M_attach(0, false); + __old->_M_detach_single(); } - for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) { _Safe_iterator_base* __old = __iter2; __iter2 = __iter2->_M_next; - __old->_M_attach(0, true); + __old->_M_detach_single(); } } - void + void _Safe_sequence_base:: _M_detach_singular() { - for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); + for (_Safe_iterator_base* __iter = _M_iterators; __iter;) { _Safe_iterator_base* __old = __iter; __iter = __iter->_M_next; if (__old->_M_singular()) - __old->_M_attach(0, false); + __old->_M_detach_single(); } - for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) { _Safe_iterator_base* __old = __iter2; __iter2 = __iter2->_M_next; if (__old->_M_singular()) - __old->_M_attach(0, true); + __old->_M_detach_single(); } } @@ -151,6 +152,7 @@ namespace __gnu_debug _Safe_sequence_base:: _M_revalidate_singular() { + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); for (_Safe_iterator_base* __iter = _M_iterators; __iter; __iter = __iter->_M_next) __iter->_M_version = _M_version; @@ -160,10 +162,11 @@ namespace __gnu_debug __iter2->_M_version = _M_version; } - void + void _Safe_sequence_base:: _M_swap(_Safe_sequence_base& __x) { + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); swap(_M_iterators, __x._M_iterators); swap(_M_const_iterators, __x._M_const_iterators); swap(_M_version, __x._M_version); @@ -177,17 +180,29 @@ namespace __gnu_debug for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next) __iter->_M_sequence = &__x; } - - void + + __gnu_cxx::__mutex& + _Safe_sequence_base:: + _M_get_mutex() + { return safe_base_mutex; } + + void _Safe_iterator_base:: _M_attach(_Safe_sequence_base* __seq, bool __constant) { - _M_detach(); + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); + _M_attach_single(__seq, __constant); + } + + void + _Safe_iterator_base:: + _M_attach_single(_Safe_sequence_base* __seq, bool __constant) + { + _M_detach_single(); // Attach to the new sequence (if there is one) if (__seq) { - __gnu_cxx::__scoped_lock sentry(iterator_base_mutex); _M_sequence = __seq; _M_version = _M_sequence->_M_version; _M_prior = 0; @@ -208,11 +223,18 @@ namespace __gnu_debug } } - void + void _Safe_iterator_base:: _M_detach() { - __gnu_cxx::__scoped_lock sentry(iterator_base_mutex); + __gnu_cxx::__scoped_lock sentry(safe_base_mutex); + _M_detach_single(); + } + + void + _Safe_iterator_base:: + _M_detach_single() + { if (_M_sequence) { // Remove us from this sequence's list @@ -232,7 +254,7 @@ namespace __gnu_debug _M_prior = 0; _M_next = 0; } - + bool _Safe_iterator_base:: _M_singular() const @@ -246,6 +268,11 @@ namespace __gnu_debug && !__x._M_singular() && _M_sequence == __x._M_sequence); } + __gnu_cxx::__mutex& + _Safe_iterator_base:: + _M_get_mutex() + { return safe_base_mutex; } + void _Error_formatter::_Parameter:: _M_print_field(const _Error_formatter* __formatter, const char* __name) const diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 6ed559f3e73..e26f009519d 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -188,6 +188,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.7"); known_versions.push_back("GLIBCXX_3.4.8"); known_versions.push_back("GLIBCXX_3.4.9"); + known_versions.push_back("GLIBCXX_3.4.10"); known_versions.push_back("GLIBCXX_LDBL_3.4"); known_versions.push_back("GLIBCXX_LDBL_3.4.7"); known_versions.push_back("CXXABI_1.3");