From: Jonathan Wakely Date: Mon, 24 Oct 2011 23:26:25 +0000 (+0000) Subject: re PR libstdc++/49894 ([C++0x] Uniform initialization in constructor) X-Git-Tag: releases/gcc-4.7.0~2845 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b81e920eac7f45b510c3430cc48dfb321a944c2f;p=thirdparty%2Fgcc.git re PR libstdc++/49894 ([C++0x] Uniform initialization in constructor) PR libstdc++/49894 * include/std/mutex (__mutex_base,__recursive_mutex_base): Define new base classes to manage construction/destruction of native mutexes, using NSDMI when INIT macros are defined. (mutex,recursive_mutex,timed_mutex,recursive_timed_mutex): Derive from new base classes. * include/std/condition_variable (condition_variable): Use NSDMI when INIT macro is defined. Use noexcept. * src/condition_variable.cc (condition_variable): Explicitly-default constructor/destructor when using NSDMI. Use noexcept. (condition_variable_any): Likewise. From-SVN: r180411 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2670e589f9d6..a7d5335b51aa 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2011-10-25 Jonathan Wakely + + PR libstdc++/49894 + * include/std/mutex (__mutex_base,__recursive_mutex_base): Define new + base classes to manage construction/destruction of native mutexes, + using NSDMI when INIT macros are defined. + (mutex,recursive_mutex,timed_mutex,recursive_timed_mutex): Derive from + new base classes. + * include/std/condition_variable (condition_variable): Use NSDMI when + INIT macro is defined. Use noexcept. + * src/condition_variable.cc (condition_variable): Explicitly-default + constructor/destructor when using NSDMI. Use noexcept. + (condition_variable_any): Likewise. + 2011-10-24 Jonathan Wakely * testsuite/30_threads/async/49668.cc: Add missing dg-require. diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index a0a3c08794a1..ef22a1dbf02f 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -60,22 +60,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef chrono::system_clock __clock_t; typedef __gthread_cond_t __native_type; + +#ifdef __GTHREAD_COND_INIT + __native_type _M_cond = __GTHREAD_COND_INIT; +#else __native_type _M_cond; +#endif public: typedef __native_type* native_handle_type; - condition_variable() throw (); - ~condition_variable() throw (); + condition_variable() noexcept; + ~condition_variable() noexcept; condition_variable(const condition_variable&) = delete; condition_variable& operator=(const condition_variable&) = delete; void - notify_one(); + notify_one() noexcept; void - notify_all(); + notify_all() noexcept; void wait(unique_lock& __lock); @@ -174,21 +179,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: typedef condition_variable::native_handle_type native_handle_type; - condition_variable_any() throw (); - ~condition_variable_any() throw (); + condition_variable_any() noexcept; + ~condition_variable_any() noexcept; condition_variable_any(const condition_variable_any&) = delete; condition_variable_any& operator=(const condition_variable_any&) = delete; void - notify_one() + notify_one() noexcept { lock_guard __lock(_M_mutex); _M_cond.notify_one(); } void - notify_all() + notify_all() noexcept { lock_guard __lock(_M_mutex); _M_cond.notify_all(); diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index a1a63b27f334..4d154ff6f0c4 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -52,6 +52,94 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION + // Common base class for std::mutex and std::timed_mutex + class __mutex_base + { + protected: + typedef __gthread_mutex_t __native_type; + +#ifdef __GTHREAD_MUTEX_INIT + __native_type _M_mutex = __GTHREAD_MUTEX_INIT; + + constexpr __mutex_base() noexcept = default; +#else + __native_type _M_mutex; + + __mutex_base() noexcept + { + // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); + } + + ~__mutex_base() { __gthread_mutex_destroy(&_M_mutex); } +#endif + + __mutex_base(const __mutex_base&) = delete; + __mutex_base& operator=(const __mutex_base&) = delete; + }; + + // Common base class for std::recursive_mutex and std::timed_recursive_mutex + class __recursive_mutex_base + { + protected: + typedef __gthread_recursive_mutex_t __native_type; + + __recursive_mutex_base(const __recursive_mutex_base&) = delete; + __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete; + +#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT + __native_type _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; + + __recursive_mutex_base() = default; +#else + __native_type _M_mutex; + + __recursive_mutex_base() + { + // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) + __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); + } + + ~__recursive_mutex_base() + { _S_destroy(&_M_mutex); } + + private: + // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy + // so we need to obtain a __gthread_mutex_t to destroy + + // matches when there's only one mutex type + template + static + typename enable_if::value, void>::type + _S_destroy(_Rm* __mx) + { __gthread_mutex_destroy(__mx); } + + // matches a recursive mutex with a member 'actual' + template + static typename enable_if::type + _S_destroy(_Rm* __mx) + { __gthread_mutex_destroy(&__mx->actual); } + + // matches a gthr-win32.h recursive mutex + template + static typename enable_if::type + _S_destroy(_Rm* __mx) + { + __gthread_mutex_t __tmp; + _S_destroy_win32(&__tmp, __mx); + } + + template + static void + _S_destroy_win32(_Mx* __mx, _Rm const* __rmx) + { + __mx->counter = __rmx->counter; + __mx->sema = __rmx->sema; + __gthread_mutex_destroy(__mx); + } +#endif + }; + /** * @defgroup mutexes Mutexes * @ingroup concurrency @@ -61,25 +149,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ /// mutex - class mutex + class mutex : private __mutex_base { - typedef __gthread_mutex_t __native_type; - __native_type _M_mutex; - public: typedef __native_type* native_handle_type; #ifdef __GTHREAD_MUTEX_INIT - constexpr mutex() noexcept : _M_mutex(__GTHREAD_MUTEX_INIT) { } -#else - mutex() noexcept - { - // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) - __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); - } - - ~mutex() { __gthread_mutex_destroy(&_M_mutex); } + constexpr #endif + mutex() noexcept = default; + ~mutex() = default; mutex(const mutex&) = delete; mutex& operator=(const mutex&) = delete; @@ -113,66 +192,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return &_M_mutex; } }; -#ifndef __GTHREAD_RECURSIVE_MUTEX_INIT - // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy - // so we need to obtain a __gthread_mutex_t to destroy - class __destroy_recursive_mutex - { - template - static void - _S_destroy_win32(_Mx* __mx, _Rm const* __rmx) - { - __mx->counter = __rmx->counter; - __mx->sema = __rmx->sema; - __gthread_mutex_destroy(__mx); - } - - public: - // matches a gthr-win32.h recursive mutex - template - static typename enable_if::type - _S_destroy(_Rm* __mx) - { - __gthread_mutex_t __tmp; - _S_destroy_win32(&__tmp, __mx); - } - - // matches a recursive mutex with a member 'actual' - template - static typename enable_if::type - _S_destroy(_Rm* __mx) - { __gthread_mutex_destroy(&__mx->actual); } - - // matches when there's only one mutex type - template - static - typename enable_if::value, void>::type - _S_destroy(_Rm* __mx) - { __gthread_mutex_destroy(__mx); } - }; -#endif - /// recursive_mutex - class recursive_mutex + class recursive_mutex : private __recursive_mutex_base { - typedef __gthread_recursive_mutex_t __native_type; - __native_type _M_mutex; - public: typedef __native_type* native_handle_type; -#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT - recursive_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { } -#else - recursive_mutex() - { - // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) - __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); - } - - ~recursive_mutex() - { __destroy_recursive_mutex::_S_destroy(&_M_mutex); } -#endif + recursive_mutex() = default; + ~recursive_mutex() = default; recursive_mutex(const recursive_mutex&) = delete; recursive_mutex& operator=(const recursive_mutex&) = delete; @@ -208,31 +235,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GTHREAD_USE_MUTEX_TIMEDLOCK /// timed_mutex - class timed_mutex + class timed_mutex : private __mutex_base { - typedef __gthread_mutex_t __native_type; - #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC typedef chrono::steady_clock __clock_t; #else typedef chrono::high_resolution_clock __clock_t; #endif - __native_type _M_mutex; - public: typedef __native_type* native_handle_type; -#ifdef __GTHREAD_MUTEX_INIT - timed_mutex() : _M_mutex(__GTHREAD_MUTEX_INIT) { } -#else - timed_mutex() - { - __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); - } - - ~timed_mutex() { __gthread_mutex_destroy(&_M_mutex); } -#endif + timed_mutex() = default; + ~timed_mutex() = default; timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; @@ -313,33 +328,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; /// recursive_timed_mutex - class recursive_timed_mutex + class recursive_timed_mutex : private __recursive_mutex_base { - typedef __gthread_recursive_mutex_t __native_type; - #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC typedef chrono::steady_clock __clock_t; #else typedef chrono::high_resolution_clock __clock_t; #endif - __native_type _M_mutex; - public: typedef __native_type* native_handle_type; -#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT - recursive_timed_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { } -#else - recursive_timed_mutex() - { - // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) - __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); - } - - ~recursive_timed_mutex() - { __destroy_recursive_mutex::_S_destroy(&_M_mutex); } -#endif + recursive_timed_mutex() = default; + ~recursive_timed_mutex() = default; recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; diff --git a/libstdc++-v3/src/condition_variable.cc b/libstdc++-v3/src/condition_variable.cc index 7f1e1946a551..6f9cd0b04b0c 100644 --- a/libstdc++-v3/src/condition_variable.cc +++ b/libstdc++-v3/src/condition_variable.cc @@ -30,25 +30,25 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - condition_variable::condition_variable() throw () - { #ifdef __GTHREAD_COND_INIT - __native_type __tmp = __GTHREAD_COND_INIT; - _M_cond = __tmp; + condition_variable::condition_variable() = default; + condition_variable::~condition_variable() = default; #else + condition_variable::condition_variable() noexcept + { int __e = __gthread_cond_init(&_M_cond, 0); if (__e) __throw_system_error(__e); -#endif } - condition_variable::~condition_variable() throw () + condition_variable::~condition_variable() noexcept { // XXX no thread blocked /* int __e = */ __gthread_cond_destroy(&_M_cond); // if __e == EBUSY then blocked } +#endif void condition_variable::wait(unique_lock& __lock) @@ -60,7 +60,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - condition_variable::notify_one() + condition_variable::notify_one() noexcept { int __e = __gthread_cond_signal(&_M_cond); @@ -71,7 +71,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - condition_variable::notify_all() + condition_variable::notify_all() noexcept { int __e = __gthread_cond_broadcast(&_M_cond); @@ -81,11 +81,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_system_error(__e); } - condition_variable_any::condition_variable_any() throw () - { } + condition_variable_any::condition_variable_any() noexcept = default; - condition_variable_any::~condition_variable_any() throw () - { } + condition_variable_any::~condition_variable_any() noexcept = default; _GLIBCXX_END_NAMESPACE_VERSION } // namespace