mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/46455 (resource leaks due to missing destructors for mutexes and condvars)
2010-11-18 Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/46455 * include/std/mutex: Define destructors for mutex types which use an init function. * include/ext/concurrence.h: Likewise. From-SVN: r166917
This commit is contained in:
parent
c9d84d0e00
commit
9916a9e47b
|
|
@ -1,3 +1,10 @@
|
||||||
|
2010-11-18 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
PR libstdc++/46455
|
||||||
|
* include/std/mutex: Define destructors for mutex types which use an
|
||||||
|
init function.
|
||||||
|
* include/ext/concurrence.h: Likewise.
|
||||||
|
|
||||||
2010-11-18 Paolo Carlini <paolo.carlini@oracle.com>
|
2010-11-18 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR libstdc++/26211 + N3168
|
PR libstdc++/26211 + N3168
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <bits/gthr.h>
|
#include <bits/gthr.h>
|
||||||
#include <bits/functexcept.h>
|
#include <bits/functexcept.h>
|
||||||
|
#include <bits/cpp_type_traits.h>
|
||||||
|
#include <ext/type_traits.h>
|
||||||
|
|
||||||
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
|
|
||||||
|
|
@ -161,6 +163,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
|
||||||
|
~__mutex()
|
||||||
|
{
|
||||||
|
if (__gthread_active_p())
|
||||||
|
__gthread_mutex_destroy(&_M_mutex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void lock()
|
void lock()
|
||||||
{
|
{
|
||||||
#if __GTHREADS
|
#if __GTHREADS
|
||||||
|
|
@ -211,6 +221,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
|
||||||
|
~__recursive_mutex()
|
||||||
|
{
|
||||||
|
if (__gthread_active_p())
|
||||||
|
_S_destroy(&_M_mutex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void lock()
|
void lock()
|
||||||
{
|
{
|
||||||
#if __GTHREADS
|
#if __GTHREADS
|
||||||
|
|
@ -235,6 +253,43 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
|
|
||||||
__gthread_recursive_mutex_t* gthread_recursive_mutex(void)
|
__gthread_recursive_mutex_t* gthread_recursive_mutex(void)
|
||||||
{ return &_M_mutex; }
|
{ return &_M_mutex; }
|
||||||
|
|
||||||
|
#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
|
||||||
|
// FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy
|
||||||
|
// so we need to obtain a __gthread_mutex_t to destroy
|
||||||
|
private:
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<std::__are_same<_Rm, __gthread_mutex_t>::__value,
|
||||||
|
void>::__type
|
||||||
|
_S_destroy(_Rm* __mx)
|
||||||
|
{ __gthread_mutex_destroy(__mx); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Scoped lock idiom.
|
/// Scoped lock idiom.
|
||||||
|
|
@ -284,6 +339,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __GTHREADS && ! defined __GTHREAD_COND_INIT
|
||||||
|
~__cond()
|
||||||
|
{
|
||||||
|
if (__gthread_active_p())
|
||||||
|
__gthread_cond_destroy(&_M_cond);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void broadcast()
|
void broadcast()
|
||||||
{
|
{
|
||||||
#if __GTHREADS
|
#if __GTHREADS
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
||||||
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
|
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~mutex() { __gthread_mutex_destroy(&_M_mutex); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutex(const mutex&) = delete;
|
mutex(const mutex&) = delete;
|
||||||
|
|
@ -109,6 +111,45 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
{ return &_M_mutex; }
|
{ 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
|
/// recursive_mutex
|
||||||
class recursive_mutex
|
class recursive_mutex
|
||||||
{
|
{
|
||||||
|
|
@ -118,17 +159,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
public:
|
public:
|
||||||
typedef __native_type* native_handle_type;
|
typedef __native_type* native_handle_type;
|
||||||
|
|
||||||
|
#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
|
||||||
|
recursive_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { }
|
||||||
|
#else
|
||||||
recursive_mutex()
|
recursive_mutex()
|
||||||
{
|
{
|
||||||
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
||||||
#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
|
|
||||||
__native_type __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
|
|
||||||
_M_mutex = __tmp;
|
|
||||||
#else
|
|
||||||
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
|
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~recursive_mutex()
|
||||||
|
{ __destroy_recursive_mutex::_S_destroy(&_M_mutex); }
|
||||||
|
#endif
|
||||||
|
|
||||||
recursive_mutex(const recursive_mutex&) = delete;
|
recursive_mutex(const recursive_mutex&) = delete;
|
||||||
recursive_mutex& operator=(const recursive_mutex&) = delete;
|
recursive_mutex& operator=(const recursive_mutex&) = delete;
|
||||||
|
|
||||||
|
|
@ -177,16 +220,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
public:
|
public:
|
||||||
typedef __native_type* native_handle_type;
|
typedef __native_type* native_handle_type;
|
||||||
|
|
||||||
|
#ifdef __GTHREAD_MUTEX_INIT
|
||||||
|
timed_mutex() : _M_mutex(__GTHREAD_MUTEX_INIT) { }
|
||||||
|
#else
|
||||||
timed_mutex()
|
timed_mutex()
|
||||||
{
|
{
|
||||||
#ifdef __GTHREAD_MUTEX_INIT
|
|
||||||
__native_type __tmp = __GTHREAD_MUTEX_INIT;
|
|
||||||
_M_mutex = __tmp;
|
|
||||||
#else
|
|
||||||
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
|
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~timed_mutex() { __gthread_mutex_destroy(&_M_mutex); }
|
||||||
|
#endif
|
||||||
|
|
||||||
timed_mutex(const timed_mutex&) = delete;
|
timed_mutex(const timed_mutex&) = delete;
|
||||||
timed_mutex& operator=(const timed_mutex&) = delete;
|
timed_mutex& operator=(const timed_mutex&) = delete;
|
||||||
|
|
||||||
|
|
@ -281,17 +325,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
public:
|
public:
|
||||||
typedef __native_type* native_handle_type;
|
typedef __native_type* native_handle_type;
|
||||||
|
|
||||||
|
#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
|
||||||
|
recursive_timed_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { }
|
||||||
|
#else
|
||||||
recursive_timed_mutex()
|
recursive_timed_mutex()
|
||||||
{
|
{
|
||||||
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
|
||||||
#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
|
|
||||||
__native_type __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
|
|
||||||
_M_mutex = __tmp;
|
|
||||||
#else
|
|
||||||
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
|
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~recursive_timed_mutex()
|
||||||
|
{ __destroy_recursive_mutex::_S_destroy(&_M_mutex); }
|
||||||
|
#endif
|
||||||
|
|
||||||
recursive_timed_mutex(const recursive_timed_mutex&) = delete;
|
recursive_timed_mutex(const recursive_timed_mutex&) = delete;
|
||||||
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
|
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue