summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread')
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp114
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp95
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/mutex.hpp142
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/once.hpp505
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp313
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp29
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp287
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp125
-rw-r--r--3rdParty/Boost/src/boost/thread/pthread/timespec.hpp108
9 files changed, 1434 insertions, 284 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
index aa71007..b1b76b0 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp
@@ -4,11 +4,13 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-10 Anthony Williams
-// (C) Copyright 2011 Vicente J. Botet Escriba
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/thread/pthread/timespec.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/pthread/thread_data.hpp>
+#endif
#include <boost/thread/pthread/condition_variable_fwd.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
@@ -20,10 +22,12 @@
namespace boost
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
}
+#endif
namespace thread_cv_detail
{
@@ -53,57 +57,88 @@ namespace boost
inline void condition_variable::wait(unique_lock<mutex>& m)
{
+#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+ if(! m.owns_lock())
+ {
+ boost::throw_exception(condition_error(-1, "boost::condition_variable::wait() failed precondition mutex not owned"));
+ }
+#endif
int res=0;
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
do {
res = pthread_cond_wait(&cond,&internal_mutex);
} while (res == EINTR);
+#else
+ //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+ do {
+ res = pthread_cond_wait(&cond,the_mutex);
+ } while (res == EINTR);
+#endif
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
+#endif
if(res)
{
- boost::throw_exception(condition_error(res, "boost:: condition_variable constructor failed in pthread_cond_wait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
}
}
- inline bool condition_variable::do_timed_wait(
+ inline bool condition_variable::do_wait_until(
unique_lock<mutex>& m,
struct timespec const &timeout)
{
+#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
if (!m.owns_lock())
- boost::throw_exception(condition_error(EPERM, "condition_variable do_timed_wait: mutex not locked"));
-
+ {
+ boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
+ }
+#endif
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
int cond_res;
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
guard.activate(m);
cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+#else
+ //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+ cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
+#endif
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
+#endif
if(cond_res==ETIMEDOUT)
{
return false;
}
if(cond_res)
{
- boost::throw_exception(condition_error(cond_res, "condition_variable failed in pthread_cond_timedwait"));
+ boost::throw_exception(condition_error(cond_res, "boost::condition_variable::do_wait_until failed in pthread_cond_timedwait"));
}
return true;
}
inline void condition_variable::notify_one() BOOST_NOEXCEPT
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+#endif
BOOST_VERIFY(!pthread_cond_signal(&cond));
}
inline void condition_variable::notify_all() BOOST_NOEXCEPT
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+#endif
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
}
@@ -119,13 +154,13 @@ namespace boost
int const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
- boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_mutex_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_cond_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
}
}
~condition_variable_any()
@@ -140,14 +175,20 @@ namespace boost
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+#else
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+#endif
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
+#endif
if(res)
{
- boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_wait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::wait() failed in pthread_cond_wait"));
}
}
@@ -157,16 +198,17 @@ namespace boost
while(!pred()) wait(m);
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
- struct timespec const timeout=detail::get_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ struct timespec const timeout=detail::to_timespec(abs_time);
+ return do_wait_until(m, timeout);
}
template<typename lock_type>
- bool timed_wait(lock_type& m,xtime const& wait_until)
+ bool timed_wait(lock_type& m,xtime const& abs_time)
{
- return timed_wait(m,system_time(wait_until));
+ return timed_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -176,20 +218,20 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
- bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
{
while (!pred())
{
- if(!timed_wait(m, wait_until))
+ if(!timed_wait(m, abs_time))
return pred();
}
return true;
}
template<typename lock_type,typename predicate_type>
- bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
+ bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
{
- return timed_wait(m,system_time(wait_until),pred);
+ return timed_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>
@@ -197,7 +239,7 @@ namespace boost
{
return timed_wait(m,get_system_time()+wait_duration,pred);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
@@ -265,26 +307,26 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- while (!pred())
- {
- if (wait_for(lock, d) == cv_status::timeout)
- return pred();
- }
- return true;
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+
+// while (!pred())
+// {
+// if (wait_for(lock, d) == cv_status::timeout)
+// return pred();
+// }
+// return true;
}
template <class lock_type>
- inline void wait_until(
+ cv_status wait_until(
lock_type& lk,
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());
- do_timed_wait(lk, ts);
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
}
#endif
@@ -302,25 +344,31 @@ namespace boost
private: // used by boost::thread::try_join_until
template <class lock_type>
- inline bool do_timed_wait(
+ inline bool do_wait_until(
lock_type& m,
struct timespec const &timeout)
{
int res=0;
{
thread_cv_detail::lock_on_exit<lock_type> guard;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+#else
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
}
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
+#endif
if(res==ETIMEDOUT)
{
return false;
}
if(res)
{
- boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_timedwait"));
+ boost::throw_exception(condition_error(res, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
}
return true;
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
index dbb3892..e18030f 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp
@@ -4,22 +4,26 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-8 Anthony Williams
-// (C) Copyright 2011 Vicente J. Botet Escriba
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include <boost/thread/cv_status.hpp>
#include <boost/thread/mutex.hpp>
-#include <boost/thread/locks.hpp>
+#include <boost/thread/lock_types.hpp>
#include <boost/thread/thread_time.hpp>
+#include <boost/thread/pthread/timespec.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
+
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -28,33 +32,58 @@ namespace boost
class condition_variable
{
private:
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
pthread_mutex_t internal_mutex;
+#endif
pthread_cond_t cond;
public:
+ //private: // used by boost::thread::try_join_until
+
+ inline bool do_wait_until(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout);
+
+ bool do_wait_for(
+ unique_lock<mutex>& lock,
+ struct timespec const &timeout)
+ {
+ return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
+ }
+
+ public:
BOOST_THREAD_NO_COPYABLE(condition_variable)
condition_variable()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
int const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
- boost::throw_exception(thread_resource_error(res, "boost:: condition_variable constructor failed in pthread_mutex_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
+#endif
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res2, "boost:: condition_variable constructor failed in pthread_cond_init"));
+#endif
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
}
}
~condition_variable()
{
- BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
int ret;
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ do {
+ ret = pthread_mutex_destroy(&internal_mutex);
+ } while (ret == EINTR);
+ BOOST_ASSERT(!ret);
+#endif
do {
ret = pthread_cond_destroy(&cond);
} while (ret == EINTR);
- BOOST_VERIFY(!ret);
+ BOOST_ASSERT(!ret);
}
void wait(unique_lock<mutex>& m);
@@ -66,23 +95,24 @@ namespace boost
}
+#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
- boost::system_time const& wait_until)
+ boost::system_time const& abs_time)
{
#if defined BOOST_THREAD_WAIT_BUG
- struct timespec const timeout=detail::get_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
- return do_timed_wait(m, timeout);
+ struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
+ return do_wait_until(m, timeout);
#else
- struct timespec const timeout=detail::get_timespec(wait_until);
- return do_timed_wait(m, timeout);
+ struct timespec const timeout=detail::to_timespec(abs_time);
+ return do_wait_until(m, timeout);
#endif
}
bool timed_wait(
unique_lock<mutex>& m,
- xtime const& wait_until)
+ xtime const& abs_time)
{
- return timed_wait(m,system_time(wait_until));
+ return timed_wait(m,system_time(abs_time));
}
template<typename duration_type>
@@ -96,11 +126,11 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
- boost::system_time const& wait_until,predicate_type pred)
+ boost::system_time const& abs_time,predicate_type pred)
{
while (!pred())
{
- if(!timed_wait(m, wait_until))
+ if(!timed_wait(m, abs_time))
return pred();
}
return true;
@@ -109,9 +139,9 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
- xtime const& wait_until,predicate_type pred)
+ xtime const& abs_time,predicate_type pred)
{
- return timed_wait(m,system_time(wait_until),pred);
+ return timed_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>
@@ -121,6 +151,7 @@ namespace boost
{
return timed_wait(m,get_system_time()+wait_duration,pred);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -190,12 +221,14 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
- while (!pred())
- {
- if (wait_for(lock, d) == cv_status::timeout)
- return pred();
- }
- return true;
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+
+// while (!pred())
+// {
+// if (wait_for(lock, d) == cv_status::timeout)
+// return pred();
+// }
+// return true;
}
#endif
@@ -210,27 +243,21 @@ namespace boost
void notify_all() BOOST_NOEXCEPT;
#ifdef BOOST_THREAD_USES_CHRONO
- inline void wait_until(
+ inline cv_status wait_until(
unique_lock<mutex>& lk,
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());
- do_timed_wait(lk, ts);
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
}
#endif
- //private: // used by boost::thread::try_join_until
-
- inline bool do_timed_wait(
- unique_lock<mutex>& lock,
- struct timespec const &timeout);
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
index 2c5af92..3e9af2a 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp
@@ -6,10 +6,14 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/detail/config.hpp>
#include <pthread.h>
#include <boost/throw_exception.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
#include <boost/thread/thread_time.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/assert.hpp>
@@ -23,15 +27,68 @@
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
-#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L
+#if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_PTHREAD_HAS_TIMEDLOCK
#endif
#endif
+#endif
+
#include <boost/config/abi_prefix.hpp>
+#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
+#define BOOST_THREAD_HAS_EINTR_BUG
+#endif
+
namespace boost
{
+ namespace posix {
+#ifdef BOOST_THREAD_HAS_EINTR_BUG
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_destroy(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_lock(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+ {
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_unlock(m);
+ } while (ret == EINTR);
+ return ret;
+ }
+#else
+ BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_destroy(m);
+ }
+ BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_lock(m);
+ }
+ BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+ {
+ return ::pthread_mutex_unlock(m);
+ }
+
+#endif
+
+ }
class mutex
{
private:
@@ -49,20 +106,14 @@ namespace boost
}
~mutex()
{
- int ret;
- do
- {
- ret = pthread_mutex_destroy(&m);
- } while (ret == EINTR);
+ int const res = posix::pthread_mutex_destroy(&m);
+ boost::ignore_unused(res);
+ BOOST_ASSERT(!res);
}
void lock()
{
- int res;
- do
- {
- res = pthread_mutex_lock(&m);
- } while (res == EINTR);
+ int res = posix::pthread_mutex_lock(&m);
if (res)
{
boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
@@ -71,12 +122,11 @@ namespace boost
void unlock()
{
- int ret;
- do
+ int res = posix::pthread_mutex_unlock(&m);
+ if (res)
{
- ret = pthread_mutex_unlock(&m);
- } while (ret == EINTR);
- BOOST_VERIFY(!ret);
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+ }
}
bool try_lock()
@@ -86,12 +136,8 @@ namespace boost
{
res = pthread_mutex_trylock(&m);
} while (res == EINTR);
- if(res && (res!=EBUSY))
+ if (res==EBUSY)
{
- // 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;
}
@@ -105,8 +151,10 @@ namespace boost
return &m;
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<mutex> scoped_lock;
typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+#endif
};
typedef mutex try_mutex;
@@ -132,7 +180,8 @@ namespace boost
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
+ //BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
}
is_locked=false;
@@ -140,12 +189,13 @@ namespace boost
}
~timed_mutex()
{
- BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#endif
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
@@ -155,23 +205,39 @@ namespace boost
{
return timed_lock(system_time(absolute_time));
}
-
+#endif
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
void lock()
{
- BOOST_VERIFY(!pthread_mutex_lock(&m));
+ int res = posix::pthread_mutex_lock(&m);
+ if (res)
+ {
+ boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));
+ }
}
void unlock()
{
- BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ int res = posix::pthread_mutex_unlock(&m);
+ if (res)
+ {
+ boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
+ }
}
bool try_lock()
{
- int const res=pthread_mutex_trylock(&m);
- BOOST_ASSERT(!res || res==EBUSY);
- return !res;
+ int res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
}
@@ -232,12 +298,13 @@ namespace boost
public:
#endif
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const & abs_time)
{
- struct timespec const ts=detail::get_timespec(abs_time);
+ struct timespec const ts=boost::detail::to_timespec(abs_time);
return do_try_lock_until(ts);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
@@ -261,12 +328,9 @@ namespace boost
}
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());
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
return do_try_lock_until(ts);
}
#endif
@@ -278,9 +342,11 @@ namespace boost
return &m;
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
+#endif
};
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/once.hpp b/3rdParty/Boost/src/boost/thread/pthread/once.hpp
index 02c2732..0bef038 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/once.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/once.hpp
@@ -11,11 +11,14 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/detail/delete.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -26,21 +29,32 @@
namespace boost
{
-#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+ struct once_flag;
+
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
namespace thread_detail
{
-//#ifdef SIG_ATOMIC_MAX
-// typedef sig_atomic_t uintmax_atomic_t;
-// #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX
-//#else
- typedef unsigned long uintmax_atomic_t;
- #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul
+ typedef boost::uint32_t uintmax_atomic_t;
+ #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##u
#define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
-//#endif
+
}
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+#endif
struct once_flag
{
@@ -50,11 +64,26 @@ namespace boost
{}
private:
volatile thread_detail::uintmax_atomic_t epoch;
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template<typename Function, class ...ArgTypes>
+ friend void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args);
+#else
template<typename Function>
- friend
- void call_once(once_flag& flag,Function f);
+ friend void call_once(once_flag& flag, Function f);
+ template<typename Function, typename T1>
+ friend void call_once(once_flag& flag, Function f, T1 p1);
+ template<typename Function, typename T1, typename T2>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2);
+ template<typename Function, typename T1, typename T2, typename T3>
+ friend void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3);
+
+#endif
+
};
+#define BOOST_ONCE_INIT once_flag()
+
#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
@@ -65,59 +94,445 @@ namespace boost
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
- namespace detail
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+ namespace thread_detail
{
- BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
- BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
+ BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
+ BOOST_THREAD_DECL extern uintmax_atomic_t once_global_epoch;
BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
}
// Based on Mike Burrows fast_pthread_once algorithm as described in
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
- template<typename Function>
- void call_once(once_flag& flag,Function f)
+
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+
+ }
+ }
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
{
- static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
- static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
- thread_detail::uintmax_atomic_t const epoch=flag.epoch;
- thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch();
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
- if(epoch<this_thread_epoch)
+ while(flag.epoch<=being_initialized)
{
- pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
+
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
+ {
+ flag.epoch=being_initialized;
+ BOOST_TRY
+ {
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
+ }
+ }
+ }
+ this_thread_epoch=thread_detail::once_global_epoch;
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+ static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
+ thread_detail::uintmax_atomic_t const epoch=flag.epoch;
+ thread_detail::uintmax_atomic_t& this_thread_epoch=thread_detail::get_once_per_thread_epoch();
- while(flag.epoch<=being_initialized)
+ if(epoch<this_thread_epoch)
+ {
+ pthread::pthread_mutex_scoped_lock lk(&thread_detail::once_epoch_mutex);
+
+ while(flag.epoch<=being_initialized)
+ {
+ if(flag.epoch==uninitialized_flag)
{
- if(flag.epoch==uninitialized_flag)
+ flag.epoch=being_initialized;
+ BOOST_TRY
{
- flag.epoch=being_initialized;
- BOOST_TRY
- {
- pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
- f();
- }
- BOOST_CATCH (...)
- {
- flag.epoch=uninitialized_flag;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- flag.epoch=--detail::once_global_epoch;
- BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
+ pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
}
- else
+ BOOST_CATCH (...)
{
- while(flag.epoch==being_initialized)
- {
- BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex));
- }
+ flag.epoch=uninitialized_flag;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ flag.epoch=--thread_detail::once_global_epoch;
+ BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
+ }
+ else
+ {
+ while(flag.epoch==being_initialized)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
- this_thread_epoch=detail::once_global_epoch;
}
+ this_thread_epoch=thread_detail::once_global_epoch;
}
+ }
+
+#endif
+
}
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp b/3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp
new file mode 100644
index 0000000..923f07b
--- /dev/null
+++ b/3rdParty/Boost/src/boost/thread/pthread/once_atomic.hpp
@@ -0,0 +1,313 @@
+#ifndef BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
+
+// once.hpp
+//
+// (C) Copyright 2013 Andrey Semashev
+// (C) Copyright 2013 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 <boost/thread/detail/config.hpp>
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/bind.hpp>
+#include <boost/atomic.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ struct once_flag;
+
+ namespace thread_detail
+ {
+
+#if BOOST_ATOMIC_INT_LOCK_FREE == 2
+ typedef unsigned int atomic_int_type;
+#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
+ typedef unsigned short atomic_int_type;
+#elif BOOST_ATOMIC_CHAR_LOCK_FREE == 2
+ typedef unsigned char atomic_int_type;
+#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
+ typedef unsigned long atomic_int_type;
+#elif defined(BOOST_HAS_LONG_LONG) && BOOST_ATOMIC_LLONG_LOCK_FREE == 2
+ typedef ulong_long_type atomic_int_type;
+#else
+ // All tested integer types are not atomic, the spinlock pool will be used
+ typedef unsigned int atomic_int_type;
+#endif
+
+ typedef boost::atomic<atomic_int_type> atomic_type;
+
+ BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+ struct once_flag
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT : storage(0)
+ {
+ }
+
+ private:
+ thread_detail::atomic_type storage;
+
+ friend BOOST_THREAD_DECL bool thread_detail::enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend BOOST_THREAD_DECL void thread_detail::commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend BOOST_THREAD_DECL void thread_detail::rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend thread_detail::atomic_type& thread_detail::get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
+ };
+
+#define BOOST_ONCE_INIT boost::once_flag()
+
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ //return reinterpret_cast< atomic_type& >(flag.storage);
+ return flag.storage;
+ }
+ }
+
+#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
+ struct once_flag
+ {
+ // The thread_detail::atomic_int_type storage is marked
+ // with this attribute in order to let the compiler know that it will alias this member
+ // and silence compilation warnings.
+ BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
+ };
+
+ #define BOOST_ONCE_INIT {0}
+
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ return reinterpret_cast< atomic_type& >(flag.storage);
+ }
+
+ }
+
+#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+#else
+ template<typename Function>
+ inline void call_once(once_flag& flag, Function f)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, Function f, T1 p1)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+ template<typename Function, typename T1>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ if (thread_detail::enter_once_region(flag))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+
+ }
+ BOOST_CATCH (...)
+ {
+ thread_detail::rollback_once_region(flag);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ thread_detail::commit_once_region(flag);
+ }
+ }
+
+
+
+#endif
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
index 2a6bc7d..9330d77 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp
@@ -9,7 +9,9 @@
#include <pthread.h>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
+#include <boost/thread/lock_types.hpp>
+#endif
#include <boost/thread/thread_time.hpp>
#include <boost/assert.hpp>
#ifndef _WIN32
@@ -26,10 +28,13 @@
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
-#if _POSIX_TIMEOUTS >= 0
+#if _POSIX_TIMEOUTS >= 0 && _POSIX_TIMEOUTS>=200112L
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_PTHREAD_HAS_TIMEDLOCK
#endif
#endif
+#endif
+
#if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
@@ -167,8 +172,10 @@ namespace boost
#endif
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
typedef unique_lock<recursive_mutex> scoped_lock;
typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+#endif
};
typedef recursive_mutex recursive_try_mutex;
@@ -232,11 +239,13 @@ namespace boost
#endif
}
+#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
+#endif
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
void lock()
@@ -334,12 +343,13 @@ namespace boost
#endif
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const & abs_time)
{
- struct timespec const ts=detail::get_timespec(abs_time);
+ struct timespec const ts=detail::to_timespec(abs_time);
return do_try_lock_until(ts);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
@@ -363,12 +373,9 @@ namespace boost
}
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());
+ //using namespace chrono;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
return do_try_lock_until(ts);
}
#endif
@@ -380,9 +387,11 @@ namespace boost
return &m;
}
+#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
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;
+#endif
};
}
diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
index cf45188..458d6c8 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp
@@ -12,12 +12,15 @@
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/detail/thread_interruption.hpp>
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
+#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -26,8 +29,125 @@ namespace boost
class shared_mutex
{
private:
- struct state_data
+ class state_data
{
+ public:
+ state_data () :
+ shared_count(0),
+ exclusive(false),
+ upgrade(false),
+ exclusive_waiting_blocked(false)
+ {}
+
+ void assert_free() const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( ! upgrade );
+ BOOST_ASSERT( shared_count==0 );
+ }
+
+ void assert_locked() const
+ {
+ BOOST_ASSERT( exclusive );
+ BOOST_ASSERT( shared_count==0 );
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ void assert_lock_shared () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( shared_count>0 );
+ //BOOST_ASSERT( (! upgrade) || (shared_count>1));
+ // if upgraded there are at least 2 threads sharing the mutex,
+ // except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
+ }
+
+ void assert_lock_upgraded () const
+ {
+ BOOST_ASSERT( ! exclusive );
+ BOOST_ASSERT( upgrade );
+ BOOST_ASSERT( shared_count>0 );
+ }
+
+ void assert_lock_not_upgraded () const
+ {
+ BOOST_ASSERT( ! upgrade );
+ }
+
+ bool can_lock () const
+ {
+ return ! (shared_count || exclusive);
+ }
+
+ void exclusive_blocked (bool blocked)
+ {
+ exclusive_waiting_blocked = blocked;
+ }
+
+ void lock ()
+ {
+ exclusive = true;
+ }
+
+ void unlock ()
+ {
+ exclusive = false;
+ exclusive_waiting_blocked = false;
+ }
+
+ bool can_lock_shared () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked);
+ }
+
+ bool more_shared () const
+ {
+ return shared_count > 0 ;
+ }
+ unsigned get_shared_count () const
+ {
+ return shared_count ;
+ }
+ unsigned lock_shared ()
+ {
+ return ++shared_count;
+ }
+
+
+ void unlock_shared ()
+ {
+ --shared_count;
+ }
+
+ bool unlock_shared_downgrades()
+ {
+ if (upgrade) {
+ upgrade=false;
+ exclusive=true;
+ return true;
+ } else {
+ exclusive_waiting_blocked=false;
+ return false;
+ }
+ }
+
+ void lock_upgrade ()
+ {
+ ++shared_count;
+ upgrade=true;
+ }
+ bool can_lock_upgrade () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked || upgrade);
+ }
+
+ void unlock_upgrade ()
+ {
+ upgrade=false;
+ --shared_count;
+ }
+
+ //private:
unsigned shared_count;
bool exclusive;
bool upgrade;
@@ -49,12 +169,11 @@ namespace boost
}
public:
+
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
- state_data state_={0,0,0,0};
- state=state_;
}
~shared_mutex()
@@ -63,44 +182,45 @@ namespace boost
void lock_shared()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
-
- while(state.exclusive || state.exclusive_waiting_blocked)
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_shared())
{
shared_cond.wait(lk);
}
- ++state.shared_count;
+ state.lock_shared();
}
bool try_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
- if(state.exclusive || state.exclusive_waiting_blocked)
+ if(!state.can_lock_shared())
{
return false;
}
- else
- {
- ++state.shared_count;
- return true;
- }
+ state.lock_shared();
+ return true;
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock_shared(system_time const& timeout)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
{
if(!shared_cond.timed_wait(lk,timeout))
{
return false;
}
}
- ++state.shared_count;
+ state.lock_shared();
return true;
}
@@ -109,6 +229,7 @@ namespace boost
{
return timed_lock_shared(get_system_time()+relative_time);
}
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
@@ -118,36 +239,43 @@ namespace boost
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked)
+ while(!state.can_lock_shared())
+ //while(state.exclusive || state.exclusive_waiting_blocked)
{
if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
{
return false;
}
}
- ++state.shared_count;
+ state.lock_shared();
return true;
}
#endif
void unlock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (! state.more_shared())
{
- if(state.upgrade)
+ if (state.upgrade)
{
+ // As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
+ // avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
state.upgrade=false;
state.exclusive=true;
+ lk.unlock();
upgrade_cond.notify_one();
}
else
{
state.exclusive_waiting_blocked=false;
+ lk.unlock();
}
release_waiters();
}
@@ -155,10 +283,12 @@ namespace boost
void lock()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
- while(state.shared_count || state.exclusive)
+ while (state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk);
@@ -166,10 +296,13 @@ namespace boost
state.exclusive=true;
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const& timeout)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
@@ -194,7 +327,7 @@ namespace boost
{
return timed_lock(get_system_time()+relative_time);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
@@ -204,8 +337,10 @@ namespace boost
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
@@ -228,7 +363,7 @@ namespace boost
bool try_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
if(state.shared_count || state.exclusive)
{
@@ -244,28 +379,35 @@ namespace boost
void unlock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
state.exclusive=false;
state.exclusive_waiting_blocked=false;
+ state.assert_free();
release_waiters();
}
void lock_upgrade()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
shared_cond.wait(lk);
}
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
}
+#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock_upgrade(system_time const& timeout)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(!shared_cond.timed_wait(lk,timeout))
@@ -277,7 +419,7 @@ namespace boost
break;
}
}
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
return true;
}
@@ -287,7 +429,7 @@ namespace boost
{
return timed_lock_upgrade(get_system_time()+relative_time);
}
-
+#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
@@ -297,8 +439,10 @@ namespace boost
template <class Clock, class Duration>
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
@@ -310,68 +454,75 @@ namespace boost
break;
}
}
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
return true;
}
#endif
bool try_lock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
else
{
- ++state.shared_count;
+ state.lock_shared();
state.upgrade=true;
+ state.assert_lock_upgraded();
return true;
}
}
void unlock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
- state.upgrade=false;
- bool const last_reader=!--state.shared_count;
-
- if(last_reader)
+ boost::unique_lock<boost::mutex> lk(state_change);
+ //state.upgrade=false;
+ state.unlock_upgrade();
+ if(! state.more_shared() )
{
state.exclusive_waiting_blocked=false;
release_waiters();
} else {
- shared_cond.notify_all();
+ shared_cond.notify_all();
}
}
// Upgrade <-> Exclusive
void unlock_upgrade_and_lock()
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
- --state.shared_count;
- while(state.shared_count)
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.unlock_shared();
+ while (state.more_shared())
{
upgrade_cond.wait(lk);
}
state.upgrade=false;
state.exclusive=true;
+ state.assert_locked();
}
void unlock_and_lock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
state.exclusive=false;
state.upgrade=true;
- ++state.shared_count;
+ state.lock_shared();
state.exclusive_waiting_blocked=false;
+ state.assert_lock_upgraded();
release_waiters();
}
bool try_unlock_upgrade_and_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& state.upgrade
@@ -380,6 +531,7 @@ namespace boost
state.shared_count=0;
state.exclusive=true;
state.upgrade=false;
+ state.assert_locked();
return true;
}
return false;
@@ -398,8 +550,11 @@ namespace boost
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
if (state.shared_count != 1)
{
for (;;)
@@ -422,9 +577,10 @@ namespace boost
// Shared <-> Exclusive
void unlock_and_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
state.exclusive=false;
- ++state.shared_count;
+ state.lock_shared();
state.exclusive_waiting_blocked=false;
release_waiters();
}
@@ -432,7 +588,8 @@ namespace boost
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
@@ -458,8 +615,11 @@ namespace boost
try_unlock_shared_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if (state.shared_count != 1)
{
for (;;)
@@ -483,7 +643,8 @@ namespace boost
// Shared <-> Upgrade
void unlock_upgrade_and_lock_shared()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
state.upgrade=false;
state.exclusive_waiting_blocked=false;
release_waiters();
@@ -492,7 +653,8 @@ namespace boost
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock_upgrade()
{
- boost::mutex::scoped_lock lk(state_change);
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
@@ -517,8 +679,11 @@ namespace boost
try_unlock_shared_and_lock_upgrade_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
- boost::mutex::scoped_lock lk(state_change);
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
if( state.exclusive
|| state.exclusive_waiting_blocked
|| state.upgrade
diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
index db4e09f..801f470 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp
@@ -8,13 +8,13 @@
#include <boost/thread/detail/config.hpp>
#include <boost/thread/exceptions.hpp>
-#include <boost/thread/locks.hpp>
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/lock_types.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/pthread/condition_variable_fwd.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
-#include <boost/optional.hpp>
#include <boost/assert.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
@@ -24,6 +24,10 @@
#include <vector>
#include <utility>
+#if defined(__ANDROID__)
+#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
+#endif
+
#include <pthread.h>
#include <unistd.h>
@@ -77,6 +81,7 @@ namespace boost
namespace detail
{
+ struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
@@ -107,8 +112,7 @@ namespace boost
bool joined;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
std::map<void const*,boost::detail::tss_data_node> tss_data;
- bool interrupt_enabled;
- bool interrupt_requested;
+
pthread_mutex_t* cond_mutex;
pthread_cond_t* current_cond;
typedef std::vector<std::pair<condition_variable*, mutex*>
@@ -116,27 +120,49 @@ namespace boost
> notify_list_t;
notify_list_t notify;
+ typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
+ async_states_t async_states_;
+
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ // These data must be at the end so that the access to the other fields doesn't change
+ // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined.
+ // Another option is to have them always
+ bool interrupt_enabled;
+ bool interrupt_requested;
+//#endif
thread_data_base():
+ thread_handle(0),
done(false),join_started(false),joined(false),
thread_exit_callbacks(0),
- interrupt_enabled(true),
- interrupt_requested(false),
+ cond_mutex(0),
current_cond(0),
- notify()
+ notify(),
+ async_states_()
+//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ , interrupt_enabled(true)
+ , interrupt_requested(false)
+//#endif
{}
virtual ~thread_data_base();
typedef pthread_t native_handle_type;
virtual void run()=0;
- void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
+ virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
{
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
+
+ void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
+ {
+ async_states_.push_back(as);
+ }
+
};
BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
class interruption_checker
{
thread_data_base* const thread_info;
@@ -188,71 +214,68 @@ namespace boost
}
}
};
+#endif
}
namespace this_thread
{
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts);
+ }
+
#ifdef BOOST_THREAD_USES_CHRONO
+#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
inline
void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
{
- using namespace chrono;
- boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
-
- if(thread_info)
- {
- unique_lock<mutex> lk(thread_info->sleep_mutex);
- while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {}
- }
- else
- {
- if (ns >= nanoseconds::zero())
- {
-
- # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
- timespec ts;
- ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
- ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
- BOOST_VERIFY(!pthread_delay_np(&ts));
- # elif defined(BOOST_HAS_NANOSLEEP)
- timespec ts;
- ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
- ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
- // nanosleep takes a timespec that is an offset, not
- // an absolute time.
- nanosleep(&ts, 0);
- # else
- mutex mx;
- mutex::scoped_lock lock(mx);
- condition_variable cond;
- cond.wait_for(lock, ns);
- # endif
- }
- }
+ return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns));
}
#endif
+#endif // BOOST_THREAD_USES_CHRONO
+
+ namespace no_interruption_point
+ {
+ namespace hiden
+ {
+ void BOOST_THREAD_DECL sleep_for(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_until(const timespec& ts);
+ }
+
+ #ifdef BOOST_THREAD_USES_CHRONO
+ #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+
+ inline
+ void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ {
+ return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns));
+ }
+ #endif
+ #endif // BOOST_THREAD_USES_CHRONO
+
+ } // no_interruption_point
+
void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
+#if defined BOOST_THREAD_USES_DATETIME
#ifdef __DECXXX
/// Workaround of DECCXX issue of incorrect template substitution
- template<typename TimeDuration>
- inline void sleep(TimeDuration const& rel_time)
+ template<>
+#endif
+ inline void sleep(system_time const& abs_time)
{
- this_thread::sleep(get_system_time()+rel_time);
+ return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
}
- template<>
- void BOOST_THREAD_DECL sleep(system_time const& abs_time);
-#else
- void BOOST_THREAD_DECL sleep(system_time const& abs_time);
-
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
this_thread::sleep(get_system_time()+rel_time);
}
-#endif
- }
+#endif // BOOST_THREAD_USES_DATETIME
+ } // this_thread
}
#include <boost/config/abi_suffix.hpp>
diff --git a/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp b/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
index d7465c1..82f50f6 100644
--- a/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
+++ b/3rdParty/Boost/src/boost/thread/pthread/timespec.hpp
@@ -1,34 +1,118 @@
#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
-// (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
+// (C) Copyright 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 <boost/thread/detail/config.hpp>
#include <boost/thread/thread_time.hpp>
+#if defined BOOST_THREAD_USES_DATETIME
#include <boost/date_time/posix_time/conversion.hpp>
+#endif
#include <pthread.h>
#ifndef _WIN32
#include <unistd.h>
#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/duration.hpp>
+#endif
+
+#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define BOOST_THREAD_TIMESPEC_MAC_API
+#include <sys/time.h> //for gettimeofday and timeval
+#else
+#include <time.h> // for clock_gettime
+#endif
#include <boost/config/abi_prefix.hpp>
namespace boost
{
- namespace detail
- {
- inline struct timespec get_timespec(boost::system_time const& abs_time)
- {
- struct timespec timeout={0,0};
- boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
-
- timeout.tv_sec=time_since_epoch.total_seconds();
- timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
- return timeout;
- }
+ namespace detail
+ {
+#if defined BOOST_THREAD_USES_DATETIME
+ inline struct timespec to_timespec(boost::system_time const& abs_time)
+ {
+ struct timespec timeout = { 0,0};
+ boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+
+ timeout.tv_sec=time_since_epoch.total_seconds();
+ timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
+ return timeout;
+ }
+#endif
+#if defined BOOST_THREAD_USES_CHRONO
+ inline timespec to_timespec(chrono::nanoseconds const& ns)
+ {
+ struct timespec ts;
+ ts.tv_sec = static_cast<long>(chrono::duration_cast<chrono::seconds>(ns).count());
+ ts.tv_nsec = static_cast<long>((ns - chrono::duration_cast<chrono::seconds>(ns)).count());
+ return ts;
}
+
+#endif
+
+ inline timespec to_timespec(boost::intmax_t const& ns)
+ {
+ boost::intmax_t s = ns / 1000000000l;
+ struct timespec ts;
+ ts.tv_sec = static_cast<long> (s);
+ ts.tv_nsec = static_cast<long> (ns - s * 1000000000l);
+ return ts;
+ }
+ inline boost::intmax_t to_nanoseconds_int_max(timespec const& ts)
+ {
+ return static_cast<boost::intmax_t>(ts.tv_sec) * 1000000000l + ts.tv_nsec;
+ }
+ inline bool timespec_ge_zero(timespec const& ts)
+ {
+ return (ts.tv_sec >= 0) || (ts.tv_nsec >= 0);
+ }
+ inline timespec timespec_now()
+ {
+ timespec ts;
+
+#if defined(BOOST_THREAD_TIMESPEC_MAC_API)
+ timeval tv;
+ ::gettimeofday(&tv, 0);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+#else
+ if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
+ {
+ BOOST_ASSERT(0 && "Boost::Thread - Internal Error");
+ }
+#endif
+ return ts;
+ }
+ inline timespec timespec_zero()
+ {
+ timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ return ts;
+ }
+ inline timespec timespec_plus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) + to_nanoseconds_int_max(rhs));
+ }
+ inline timespec timespec_minus(timespec const& lhs, timespec const& rhs)
+ {
+ return to_timespec(to_nanoseconds_int_max(lhs) - to_nanoseconds_int_max(rhs));
+ }
+ inline bool timespec_gt(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) > to_nanoseconds_int_max(rhs);
+ }
+ inline bool timespec_ge(timespec const& lhs, timespec const& rhs)
+ {
+ return to_nanoseconds_int_max(lhs) >= to_nanoseconds_int_max(rhs);
+ }
+
+ }
}
#include <boost/config/abi_suffix.hpp>