mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 01:30:55 +08:00
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
This commit is contained in:
parent
cca3f03dfe
commit
b81e920eac
@ -1,3 +1,17 @@
|
||||
2011-10-25 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
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 <jwakely.gcc@gmail.com>
|
||||
|
||||
* testsuite/30_threads/async/49668.cc: Add missing dg-require.
|
||||
|
@ -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<mutex>& __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<mutex> __lock(_M_mutex);
|
||||
_M_cond.notify_one();
|
||||
}
|
||||
|
||||
void
|
||||
notify_all()
|
||||
notify_all() noexcept
|
||||
{
|
||||
lock_guard<mutex> __lock(_M_mutex);
|
||||
_M_cond.notify_all();
|
||||
|
@ -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<typename _Rm>
|
||||
static
|
||||
typename enable_if<is_same<_Rm, __gthread_mutex_t>::value, void>::type
|
||||
_S_destroy(_Rm* __mx)
|
||||
{ __gthread_mutex_destroy(__mx); }
|
||||
|
||||
// matches a recursive mutex with a member 'actual'
|
||||
template<typename _Rm>
|
||||
static typename enable_if<sizeof(&_Rm::actual), void>::type
|
||||
_S_destroy(_Rm* __mx)
|
||||
{ __gthread_mutex_destroy(&__mx->actual); }
|
||||
|
||||
// matches a gthr-win32.h recursive mutex
|
||||
template<typename _Rm>
|
||||
static typename enable_if<sizeof(&_Rm::sema), void>::type
|
||||
_S_destroy(_Rm* __mx)
|
||||
{
|
||||
__gthread_mutex_t __tmp;
|
||||
_S_destroy_win32(&__tmp, __mx);
|
||||
}
|
||||
|
||||
template<typename _Mx, typename _Rm>
|
||||
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<typename _Mx, typename _Rm>
|
||||
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<typename _Rm>
|
||||
static typename enable_if<sizeof(&_Rm::sema), void>::type
|
||||
_S_destroy(_Rm* __mx)
|
||||
{
|
||||
__gthread_mutex_t __tmp;
|
||||
_S_destroy_win32(&__tmp, __mx);
|
||||
}
|
||||
|
||||
// matches a recursive mutex with a member 'actual'
|
||||
template<typename _Rm>
|
||||
static typename enable_if<sizeof(&_Rm::actual), void>::type
|
||||
_S_destroy(_Rm* __mx)
|
||||
{ __gthread_mutex_destroy(&__mx->actual); }
|
||||
|
||||
// matches when there's only one mutex type
|
||||
template<typename _Rm>
|
||||
static
|
||||
typename enable_if<is_same<_Rm, __gthread_mutex_t>::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;
|
||||
|
@ -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<mutex>& __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
|
||||
|
Loading…
x
Reference in New Issue
Block a user