Commit 9916a9e4 by Jonathan Wakely Committed by Jonathan Wakely

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
parent c9d84d0e
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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -177,16 +220,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
public: public:
typedef __native_type* native_handle_type; typedef __native_type* native_handle_type;
timed_mutex()
{
#ifdef __GTHREAD_MUTEX_INIT #ifdef __GTHREAD_MUTEX_INIT
__native_type __tmp = __GTHREAD_MUTEX_INIT; timed_mutex() : _M_mutex(__GTHREAD_MUTEX_INIT) { }
_M_mutex = __tmp;
#else #else
timed_mutex()
{
__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) ...@@ -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;
......
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