diff options
Diffstat (limited to 'boost/thread/pthread/recursive_mutex.hpp')
-rw-r--r-- | boost/thread/pthread/recursive_mutex.hpp | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/boost/thread/pthread/recursive_mutex.hpp b/boost/thread/pthread/recursive_mutex.hpp index 113a0ac15e..22acf41fa2 100644 --- a/boost/thread/pthread/recursive_mutex.hpp +++ b/boost/thread/pthread/recursive_mutex.hpp @@ -1,12 +1,12 @@ #ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP #define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <pthread.h> -#include <boost/utility.hpp> #include <boost/throw_exception.hpp> #include <boost/thread/exceptions.hpp> #include <boost/thread/locks.hpp> @@ -19,6 +19,11 @@ #include <errno.h> #include <boost/thread/pthread/timespec.hpp> #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp> #ifdef _POSIX_TIMEOUTS #if _POSIX_TIMEOUTS >= 0 @@ -37,8 +42,6 @@ namespace boost class recursive_mutex { private: - recursive_mutex(recursive_mutex const&); - recursive_mutex& operator=(recursive_mutex const&); pthread_mutex_t m; #ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE pthread_cond_t cond; @@ -47,6 +50,7 @@ namespace boost unsigned count; #endif public: + BOOST_THREAD_NO_COPYABLE(recursive_mutex) recursive_mutex() { #ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE @@ -55,33 +59,33 @@ namespace boost int const init_attr_res=pthread_mutexattr_init(&attr); if(init_attr_res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_init")); } int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); if(set_attr_res) { BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype")); } int const res=pthread_mutex_init(&m,&attr); if(res) { BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init")); } BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); #else int const res=pthread_mutex_init(&m,NULL); if(res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init")); } int const res2=pthread_cond_init(&cond,NULL); if(res2) { BOOST_VERIFY(!pthread_mutex_destroy(&m)); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init")); } is_locked=false; count=0; @@ -112,6 +116,7 @@ namespace boost BOOST_ASSERT(!res || res==EBUSY); return !res; } +#define BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE typedef pthread_mutex_t* native_handle_type; native_handle_type native_handle() { @@ -171,9 +176,6 @@ namespace boost class recursive_timed_mutex { private: - recursive_timed_mutex(recursive_timed_mutex const&); - recursive_timed_mutex& operator=(recursive_timed_mutex const&); - private: pthread_mutex_t m; #ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK pthread_cond_t cond; @@ -182,6 +184,7 @@ namespace boost unsigned count; #endif public: + BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex) recursive_timed_mutex() { #ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK @@ -190,32 +193,32 @@ namespace boost int const init_attr_res=pthread_mutexattr_init(&attr); if(init_attr_res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_init")); } int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); if(set_attr_res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype")); } int const res=pthread_mutex_init(&m,&attr); if(res) { BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init")); } BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); #else int const res=pthread_mutex_init(&m,NULL); if(res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init")); } int const res2=pthread_cond_init(&cond,NULL); if(res2) { BOOST_VERIFY(!pthread_mutex_destroy(&m)); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init")); } is_locked=false; count=0; @@ -252,19 +255,15 @@ namespace boost BOOST_ASSERT(!res || res==EBUSY); return !res; } - bool timed_lock(system_time const & abs_time) + private: + bool do_try_lock_until(struct timespec const &timeout) { - struct timespec const timeout=detail::get_timespec(abs_time); int const res=pthread_mutex_timedlock(&m,&timeout); BOOST_ASSERT(!res || res==ETIMEDOUT); return !res; } - typedef pthread_mutex_t* native_handle_type; - native_handle_type native_handle() - { - return &m; - } + public: #else void lock() @@ -308,9 +307,9 @@ namespace boost return true; } - bool timed_lock(system_time const & abs_time) + private: + bool do_try_lock_until(struct timespec const &timeout) { - struct timespec const timeout=detail::get_timespec(abs_time); boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); if(is_locked && pthread_equal(owner,pthread_self())) { @@ -331,8 +330,56 @@ namespace boost owner=pthread_self(); return true; } + public: + +#endif + + bool timed_lock(system_time const & abs_time) + { + struct timespec const ts=detail::get_timespec(abs_time); + return do_try_lock_until(ts); + } + +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + system_clock::time_point s_now = system_clock::now(); + typename Clock::time_point c_now = Clock::now(); + return try_lock_until(s_now + ceil<nanoseconds>(t - c_now)); + } + template <class Duration> + bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) + { + using namespace chrono; + typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; + return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); + } + bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) + { + using namespace chrono; + nanoseconds d = tp.time_since_epoch(); + timespec ts; + seconds s = duration_cast<seconds>(d); + ts.tv_sec = static_cast<long>(s.count()); + ts.tv_nsec = static_cast<long>((d - s).count()); + return do_try_lock_until(ts); + } #endif +#define BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + typedef unique_lock<recursive_timed_mutex> scoped_timed_lock; typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock; typedef scoped_timed_lock scoped_lock; |