summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/mutex.hpp')
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/mutex.hpp141
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;