diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/mutex.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/mutex.hpp | 141 |
1 files changed, 105 insertions, 36 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp index 2a326d7..2c5af92 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp @@ -1,12 +1,12 @@ #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP #define BOOST_THREAD_PTHREAD_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> @@ -14,11 +14,16 @@ #include <boost/thread/xtime.hpp> #include <boost/assert.hpp> #include <errno.h> -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" +#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 +#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L #define BOOST_PTHREAD_HAS_TIMEDLOCK #endif #endif @@ -30,48 +35,70 @@ namespace boost class mutex { private: - mutex(mutex const&); - mutex& operator=(mutex const&); pthread_mutex_t m; public: + BOOST_THREAD_NO_COPYABLE(mutex) + mutex() { int const res=pthread_mutex_init(&m,NULL); if(res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init")); } } ~mutex() { - BOOST_VERIFY(!pthread_mutex_destroy(&m)); + int ret; + do + { + ret = pthread_mutex_destroy(&m); + } while (ret == EINTR); } - + void lock() { - int const res=pthread_mutex_lock(&m); - if(res) + int res; + do + { + res = pthread_mutex_lock(&m); + } while (res == EINTR); + if (res) { - boost::throw_exception(lock_error(res)); + boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock")); } } void unlock() { - BOOST_VERIFY(!pthread_mutex_unlock(&m)); + int ret; + do + { + ret = pthread_mutex_unlock(&m); + } while (ret == EINTR); + BOOST_VERIFY(!ret); } - + bool try_lock() { - int const res=pthread_mutex_trylock(&m); + int res; + do + { + res = pthread_mutex_trylock(&m); + } while (res == EINTR); if(res && (res!=EBUSY)) { - boost::throw_exception(lock_error(res)); + // The following throw_exception has been replaced by an assertion and just return false, + // as this is an internal error and the user can do nothing with the exception. + //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock")); + BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock"); + return false; } - + return !res; } +#define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE typedef pthread_mutex_t* native_handle_type; native_handle_type native_handle() { @@ -87,28 +114,26 @@ namespace boost class timed_mutex { private: - timed_mutex(timed_mutex const&); - timed_mutex& operator=(timed_mutex const&); - private: pthread_mutex_t m; #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK pthread_cond_t cond; bool is_locked; #endif public: + BOOST_THREAD_NO_COPYABLE(timed_mutex) timed_mutex() { int const res=pthread_mutex_init(&m,NULL); if(res) { - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init")); } #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK 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:: timed_mutex constructor failed in pthread_cond_init")); } is_locked=false; #endif @@ -141,26 +166,23 @@ namespace boost { BOOST_VERIFY(!pthread_mutex_unlock(&m)); } - + bool try_lock() { int const res=pthread_mutex_trylock(&m); BOOST_ASSERT(!res || res==EBUSY); return !res; } - bool timed_lock(system_time const & abs_time) - { - 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() + + private: + bool do_try_lock_until(struct timespec const &timeout) { - return &m; + int const res=pthread_mutex_timedlock(&m,&timeout); + BOOST_ASSERT(!res || res==ETIMEDOUT); + return !res; } + public: #else void lock() @@ -179,7 +201,7 @@ namespace boost is_locked=false; BOOST_VERIFY(!pthread_cond_signal(&cond)); } - + bool try_lock() { boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); @@ -191,9 +213,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); while(is_locked) { @@ -207,8 +229,55 @@ namespace boost is_locked=true; 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_TIMED_MUTEX_NATIVE_HANDLE + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + typedef unique_lock<timed_mutex> scoped_timed_lock; typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock; typedef scoped_timed_lock scoped_lock; |