#ifndef _CONCURRENCE_H
#define _CONCURRENCE_H 1
#include <cstdlib>
#include <exception>
#include <bits/gthr.h>
#include <bits/functexcept.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
enum _Lock_policy { _S_single, _S_mutex, _S_atomic };
static const _Lock_policy __default_lock_policy =
#ifdef __GTHREADS
#ifdef _GLIBCXX_ATOMIC_BUILTINS
_S_atomic;
#else
_S_mutex;
#endif
#else
_S_single;
#endif
class __concurrence_lock_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_lock_error"; }
};
class __concurrence_unlock_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_unlock_error"; }
};
inline void
__throw_concurrence_lock_error()
{
#if __EXCEPTIONS
throw __concurrence_lock_error();
#else
std::abort();
#endif
}
inline void
__throw_concurrence_unlock_error()
{
#if __EXCEPTIONS
throw __concurrence_unlock_error();
#else
std::abort();
#endif
}
class __mutex
{
private:
__gthread_mutex_t _M_mutex;
__mutex(const __mutex&);
__mutex& operator=(const __mutex&);
public:
__mutex()
{
#if __GTHREADS
if (__gthread_active_p())
{
#if defined __GTHREAD_MUTEX_INIT
__gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
_M_mutex = __tmp;
#else
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
}
#endif
}
void lock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_mutex_lock(&_M_mutex) != 0)
__throw_concurrence_lock_error();
}
#endif
}
void unlock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_mutex_unlock(&_M_mutex) != 0)
__throw_concurrence_unlock_error();
}
#endif
}
};
class __recursive_mutex
{
private:
__gthread_recursive_mutex_t _M_mutex;
__recursive_mutex(const __recursive_mutex&);
__recursive_mutex& operator=(const __recursive_mutex&);
public:
__recursive_mutex()
{
#if __GTHREADS
if (__gthread_active_p())
{
#if defined __GTHREAD_RECURSIVE_MUTEX_INIT
__gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
_M_mutex = __tmp;
#else
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
}
#endif
}
void lock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
__throw_concurrence_lock_error();
}
#endif
}
void unlock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
__throw_concurrence_unlock_error();
}
#endif
}
};
class __scoped_lock
{
public:
typedef __mutex __mutex_type;
private:
__mutex_type& _M_device;
__scoped_lock(const __scoped_lock&);
__scoped_lock& operator=(const __scoped_lock&);
public:
explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
{ _M_device.lock(); }
~__scoped_lock() throw()
{ _M_device.unlock(); }
};
_GLIBCXX_END_NAMESPACE
#endif