Commit b81e920e by Jonathan Wakely Committed by Jonathan Wakely

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
parent cca3f03d
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment