summaryrefslogtreecommitdiff
path: root/src/third_party/boost-1.56.0/boost/thread/pthread
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2014-08-15 17:06:16 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2014-08-15 17:20:20 -0400
commit0d1d5016b57c59817fa0619e5cf4c6df046b28c3 (patch)
treeeae9fc8b180f49dd5e3834f7238c9c9cad93cfd9 /src/third_party/boost-1.56.0/boost/thread/pthread
parent492d97468b1121228f208489a645759b390f023e (diff)
downloadmongo-0d1d5016b57c59817fa0619e5cf4c6df046b28c3.tar.gz
SERVER-8994: Boost 1.56.0
Initial import of source Libraries: algorithm array asio bind chrono config container date_time filesystem function integer intrusive noncopyable optional program_options random smart_ptr static_assert thread unordered utility
Diffstat (limited to 'src/third_party/boost-1.56.0/boost/thread/pthread')
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable.hpp383
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable_fwd.hpp266
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/mutex.hpp357
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/once.hpp540
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/once_atomic.hpp313
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp64
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/recursive_mutex.hpp401
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex.hpp716
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex_assert.hpp724
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/thread_data.hpp283
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/thread_heap_alloc.hpp242
-rw-r--r--src/third_party/boost-1.56.0/boost/thread/pthread/timespec.hpp120
12 files changed, 4409 insertions, 0 deletions
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable.hpp
new file mode 100644
index 00000000000..b1b76b012fc
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable.hpp
@@ -0,0 +1,383 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+// 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)
+// (C) Copyright 2007-10 Anthony Williams
+// (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>
+#include <boost/chrono/ceil.hpp>
+#endif
+#include <boost/thread/detail/delete.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ namespace this_thread
+ {
+ void BOOST_THREAD_DECL interruption_point();
+ }
+#endif
+
+ namespace thread_cv_detail
+ {
+ template<typename MutexType>
+ struct lock_on_exit
+ {
+ MutexType* m;
+
+ lock_on_exit():
+ m(0)
+ {}
+
+ void activate(MutexType& m_)
+ {
+ m_.unlock();
+ m=&m_;
+ }
+ ~lock_on_exit()
+ {
+ if(m)
+ {
+ m->lock();
+ }
+ }
+ };
+ }
+
+ 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::wait failed in pthread_cond_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, "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, "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));
+ }
+
+ class condition_variable_any
+ {
+ pthread_mutex_t internal_mutex;
+ pthread_cond_t cond;
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(condition_variable_any)
+ condition_variable_any()
+ {
+ int const res=pthread_mutex_init(&internal_mutex,NULL);
+ if(res)
+ {
+ 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, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
+ }
+ }
+ ~condition_variable_any()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+ }
+
+ template<typename lock_type>
+ void wait(lock_type& m)
+ {
+ 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, "boost::condition_variable_any::wait() failed in pthread_cond_wait"));
+ }
+ }
+
+ template<typename lock_type,typename predicate_type>
+ void wait(lock_type& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time)
+ {
+ 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& abs_time)
+ {
+ return timed_wait(m,system_time(abs_time));
+ }
+
+ template<typename lock_type,typename duration_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration)
+ {
+ return timed_wait(m,get_system_time()+wait_duration);
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
+ {
+ while (!pred())
+ {
+ 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& abs_time, predicate_type pred)
+ {
+ return timed_wait(m,system_time(abs_time),pred);
+ }
+
+ template<typename lock_type,typename duration_type,typename predicate_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+#endif
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class lock_type,class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return system_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ 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();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+
+ }
+
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ 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>
+ 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 = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+
+ void notify_one() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ void notify_all() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+ BOOST_VERIFY(!pthread_cond_broadcast(&cond));
+ }
+ private: // used by boost::thread::try_join_until
+
+ template <class lock_type>
+ 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, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
+ }
+ return true;
+ }
+
+
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable_fwd.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable_fwd.hpp
new file mode 100644
index 00000000000..e18030fd5fc
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/condition_variable_fwd.hpp
@@ -0,0 +1,266 @@
+#ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+#define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+// (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/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
+{
+
+ 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::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));
+#endif
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
+ }
+ }
+ ~condition_variable()
+ {
+ 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_ASSERT(!ret);
+ }
+
+ void wait(unique_lock<mutex>& m);
+
+ template<typename predicate_type>
+ void wait(unique_lock<mutex>& m,predicate_type pred)
+ {
+ while(!pred()) wait(m);
+ }
+
+
+#if defined BOOST_THREAD_USES_DATETIME
+ inline bool timed_wait(
+ unique_lock<mutex>& m,
+ boost::system_time const& abs_time)
+ {
+#if defined BOOST_THREAD_WAIT_BUG
+ 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::to_timespec(abs_time);
+ return do_wait_until(m, timeout);
+#endif
+ }
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ xtime const& abs_time)
+ {
+ return timed_wait(m,system_time(abs_time));
+ }
+
+ template<typename duration_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ duration_type const& wait_duration)
+ {
+ return timed_wait(m,get_system_time()+wait_duration);
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ boost::system_time const& abs_time,predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!timed_wait(m, abs_time))
+ return pred();
+ }
+ return true;
+ }
+
+ template<typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ xtime const& abs_time,predicate_type pred)
+ {
+ return timed_wait(m,system_time(abs_time),pred);
+ }
+
+ template<typename duration_type,typename predicate_type>
+ bool timed_wait(
+ unique_lock<mutex>& m,
+ duration_type const& wait_duration,predicate_type pred)
+ {
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<chrono::system_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return system_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ 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();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ system_clock::time_point s_now = system_clock::now();
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+
+ }
+
+
+ template <class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ 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
+
+#define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &cond;
+ }
+
+ void notify_one() BOOST_NOEXCEPT;
+ void notify_all() BOOST_NOEXCEPT;
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ 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 = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+ };
+
+ BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/mutex.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/mutex.hpp
new file mode 100644
index 00000000000..3e9af2a833a
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/mutex.hpp
@@ -0,0 +1,357 @@
+#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 <boost/thread/detail/config.hpp>
+#include <pthread.h>
+#include <boost/throw_exception.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/thread/exceptions.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>
+#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 && _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:
+ 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(res, "boost:: mutex constructor failed in pthread_mutex_init"));
+ }
+ }
+ ~mutex()
+ {
+ int const res = posix::pthread_mutex_destroy(&m);
+ boost::ignore_unused(res);
+ BOOST_ASSERT(!res);
+ }
+
+ void lock()
+ {
+ 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()
+ {
+ 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 res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
+ }
+
+#define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ 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;
+
+ class timed_mutex
+ {
+ 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(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(!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;
+#endif
+ }
+ ~timed_mutex()
+ {
+ 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)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+ bool timed_lock(boost::xtime const & absolute_time)
+ {
+ return timed_lock(system_time(absolute_time));
+ }
+#endif
+#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+ void lock()
+ {
+ 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()
+ {
+ 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 res;
+ do
+ {
+ res = pthread_mutex_trylock(&m);
+ } while (res == EINTR);
+ if (res==EBUSY)
+ {
+ return false;
+ }
+
+ return !res;
+ }
+
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ int const res=pthread_mutex_timedlock(&m,&timeout);
+ BOOST_ASSERT(!res || res==ETIMEDOUT);
+ return !res;
+ }
+ public:
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ is_locked=false;
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked)
+ {
+ return false;
+ }
+ is_locked=true;
+ return true;
+ }
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ while(is_locked)
+ {
+ int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+ if(cond_res==ETIMEDOUT)
+ {
+ return false;
+ }
+ BOOST_ASSERT(!cond_res);
+ }
+ is_locked=true;
+ return true;
+ }
+ public:
+#endif
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const & 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)
+ {
+ 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;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ 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;
+ }
+
+#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
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/once.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/once.hpp
new file mode 100644
index 00000000000..0bef0387de7
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/once.hpp
@@ -0,0 +1,540 @@
+#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_HPP
+
+// once.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 <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/core/no_exceptions_support.hpp>
+
+#include <boost/bind.hpp>
+#include <boost/assert.hpp>
+#include <boost/config/abi_prefix.hpp>
+
+#include <boost/cstdint.hpp>
+#include <pthread.h>
+#include <csignal>
+
+namespace boost
+{
+
+ struct once_flag;
+
+ #define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+
+ namespace thread_detail
+ {
+ 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)
+
+ }
+
+#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
+ {
+ BOOST_THREAD_NO_COPYABLE(once_flag)
+ BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
+ : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
+ {}
+ 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);
+ 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
+ {
+ volatile thread_detail::uintmax_atomic_t epoch;
+ };
+
+#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
+#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
+
+ namespace thread_detail
+ {
+ 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
+
+
+#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)
+ {
+ 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))
+ ) 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();
+
+ 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)),
+ thread_detail::decay_copy(boost::forward<T1>(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;
+ }
+ }
+
+#endif
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/once_atomic.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/once_atomic.hpp
new file mode 100644
index 00000000000..923f07bd90d
--- /dev/null
+++ b/src/third_party/boost-1.56.0/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/src/third_party/boost-1.56.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
new file mode 100644
index 00000000000..cdbf8c67408
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
@@ -0,0 +1,64 @@
+#ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+#define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+// (C) Copyright 2007-8 Anthony Williams
+//
+// 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/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace pthread
+ {
+ class pthread_mutex_scoped_lock
+ {
+ pthread_mutex_t* m;
+ bool locked;
+ public:
+ explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
+ m(m_),locked(true)
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ locked=false;
+ }
+
+ ~pthread_mutex_scoped_lock()
+ {
+ if(locked)
+ {
+ unlock();
+ }
+ }
+
+ };
+
+ class pthread_mutex_scoped_unlock
+ {
+ pthread_mutex_t* m;
+ public:
+ explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_):
+ m(m_)
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ }
+ ~pthread_mutex_scoped_unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/recursive_mutex.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/recursive_mutex.hpp
new file mode 100644
index 00000000000..9330d77de97
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/recursive_mutex.hpp
@@ -0,0 +1,401 @@
+#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/throw_exception.hpp>
+#include <boost/thread/exceptions.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
+#include <unistd.h>
+#endif
+#include <boost/date_time/posix_time/conversion.hpp>
+#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 && _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
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class recursive_mutex
+ {
+ private:
+ pthread_mutex_t m;
+#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_mutex)
+ recursive_mutex()
+ {
+#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ pthread_mutexattr_t attr;
+
+ int const init_attr_res=pthread_mutexattr_init(&attr);
+ if(init_attr_res)
+ {
+ 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(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(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(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(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));
+ }
+ is_locked=false;
+ count=0;
+#endif
+ }
+ ~recursive_mutex()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+ }
+
+#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+ void lock()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(&m));
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ int const res=pthread_mutex_trylock(&m);
+ 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()
+ {
+ return &m;
+ }
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+#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;
+
+ class recursive_timed_mutex
+ {
+ private:
+ pthread_mutex_t m;
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
+ public:
+ BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
+ recursive_timed_mutex()
+ {
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ pthread_mutexattr_t attr;
+
+ int const init_attr_res=pthread_mutexattr_init(&attr);
+ if(init_attr_res)
+ {
+ 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(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(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(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(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));
+ }
+ is_locked=false;
+ count=0;
+#endif
+ }
+ ~recursive_timed_mutex()
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#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()
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(&m));
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(&m));
+ }
+
+ bool try_lock()
+ {
+ int const res=pthread_mutex_trylock(&m);
+ BOOST_ASSERT(!res || res==EBUSY);
+ return !res;
+ }
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ int const res=pthread_mutex_timedlock(&m,&timeout);
+ BOOST_ASSERT(!res || res==ETIMEDOUT);
+ return !res;
+ }
+
+ public:
+
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock() BOOST_NOEXCEPT
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+ private:
+ bool do_try_lock_until(struct timespec const &timeout)
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return true;
+ }
+ while(is_locked)
+ {
+ int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+ if(cond_res==ETIMEDOUT)
+ {
+ return false;
+ }
+ BOOST_ASSERT(!cond_res);
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+ public:
+
+#endif
+
+#if defined BOOST_THREAD_USES_DATETIME
+ bool timed_lock(system_time const & 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)
+ {
+ 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;
+ chrono::nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ 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;
+ }
+
+#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
+ };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex.hpp
new file mode 100644
index 00000000000..458d6c83613
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex.hpp
@@ -0,0 +1,716 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-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/assert.hpp>
+#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>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ 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;
+ bool exclusive_waiting_blocked;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+
+ public:
+
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+
+ shared_mutex()
+ {
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_shared())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_shared();
+ }
+
+ bool try_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(!state.can_lock_shared())
+ {
+ return false;
+ }
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ 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.lock_shared();
+ return true;
+ }
+#endif
+ void unlock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (! state.more_shared())
+ {
+ 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();
+ }
+ }
+
+ void lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while (state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ exclusive_cond.wait(lk);
+ }
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.timed_wait(lk,timeout))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ 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>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+#endif
+
+ bool try_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(state.shared_count || state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ state.exclusive=true;
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ shared_cond.wait(lk);
+ }
+ 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;
+#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))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
+ }
+ 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;
+#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))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ return true;
+ }
+#endif
+ bool try_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ state.lock_shared();
+ state.upgrade=true;
+ state.assert_lock_upgraded();
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ 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();
+ }
+ }
+
+ // Upgrade <-> Exclusive
+ void unlock_upgrade_and_lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#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::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.exclusive=false;
+ state.upgrade=true;
+ state.lock_shared();
+ state.exclusive_waiting_blocked=false;
+ state.assert_lock_upgraded();
+ release_waiters();
+ }
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ state.upgrade=false;
+ state.assert_locked();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if (state.shared_count != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if (state.shared_count == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.exclusive_waiting_blocked=false;
+ state.shared_count=0;
+ return true;
+ }
+#endif
+
+ // Shared <-> Exclusive
+ void unlock_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.exclusive=false;
+ state.lock_shared();
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ && state.shared_count==1)
+ {
+ state.shared_count=0;
+ state.exclusive=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if (state.shared_count != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if (state.shared_count == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ state.exclusive_waiting_blocked=false;
+ state.shared_count=0;
+ return true;
+ }
+#endif
+#endif
+
+ // Shared <-> Upgrade
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( !state.exclusive
+ && !state.exclusive_waiting_blocked
+ && !state.upgrade
+ )
+ {
+ state.upgrade=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( state.exclusive
+ || state.exclusive_waiting_blocked
+ || state.upgrade
+ )
+ {
+ for (;;)
+ {
+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
+ if( ! state.exclusive
+ && ! state.exclusive_waiting_blocked
+ && ! state.upgrade
+ )
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.upgrade=true;
+ return true;
+ }
+#endif
+#endif
+ };
+
+ typedef shared_mutex upgrade_mutex;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex_assert.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex_assert.hpp
new file mode 100644
index 00000000000..186ab7984bd
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/shared_mutex_assert.hpp
@@ -0,0 +1,724 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+// (C) Copyright 2006-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/assert.hpp>
+#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>
+
+namespace boost
+{
+ class shared_mutex
+ {
+ private:
+ 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 is_last_shared () const
+ {
+ return !shared_count ;
+ }
+ 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 ()
+ {
+ lock_shared ();
+ upgrade=true;
+ }
+ bool can_lock_upgrade () const
+ {
+ return ! (exclusive || exclusive_waiting_blocked || upgrade);
+ }
+
+ void unlock_upgrade ()
+ {
+ upgrade=false;
+ unlock_shared();
+ }
+
+ //private:
+ unsigned shared_count;
+ bool exclusive;
+ bool upgrade;
+ bool exclusive_waiting_blocked;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+
+ public:
+ BOOST_THREAD_NO_COPYABLE(shared_mutex)
+
+ shared_mutex()
+ {
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_shared();
+ }
+
+ bool try_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!state.can_lock_shared())
+ {
+ return false;
+ }
+ else
+ {
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
+ }
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock_shared())
+ {
+ if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
+ {
+ return false;
+ }
+ }
+ state.lock_shared();
+ return true;
+ }
+#endif
+ void unlock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ state.unlock_shared();
+ if (state.get_shared_count () == 0)
+ {
+ if (state.unlock_shared_downgrades())
+ {
+ lk.unlock();
+ upgrade_cond.notify_one();
+ } else {
+ lk.unlock();
+ }
+ release_waiters();
+ }
+ }
+
+ void lock()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ exclusive_cond.wait(lk);
+ }
+ state.lock();
+ }
+
+#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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ if(!exclusive_cond.timed_wait(lk,timeout))
+ {
+ if(!state.can_lock())
+ {
+ state.exclusive_blocked(false);
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ //state.lock();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ 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>& abs_time)
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ while(!state.can_lock())
+ {
+ state.exclusive_blocked(true);
+ if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
+ {
+ if(!state.can_lock())
+ {
+ state.exclusive_blocked(false);
+ release_waiters();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ //state.lock();
+ return true;
+ }
+#endif
+
+ bool try_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+
+ if(!state.can_lock())
+ {
+ return false;
+ }
+ else
+ {
+ state.lock();
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.assert_free();
+ release_waiters();
+ }
+
+ void lock_upgrade()
+ {
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ shared_cond.wait(lk);
+ }
+ state.lock_upgrade();
+ }
+
+#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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ if(!shared_cond.timed_wait(lk,timeout))
+ {
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_upgrade();
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ 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)
+ {
+ return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
+ }
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ while(!state.can_lock_upgrade())
+ {
+ if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
+ {
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ state.lock_upgrade();
+ return true;
+ }
+#endif
+ bool try_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!state.can_lock_upgrade())
+ {
+ return false;
+ }
+ else
+ {
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ state.unlock_upgrade();
+ state.assert_lock_not_upgraded ();
+ if(state.get_shared_count () == 0)
+ {
+ state.exclusive_blocked(false);
+ lk.unlock();
+ release_waiters();
+ } else {
+ lk.unlock();
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ // assert state.get_shared_count() >=1
+ while(
+ //! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&&
+ state.get_shared_count()!=1)
+ {
+ upgrade_cond.wait(lk);
+ }
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.lock_upgrade();
+ state.assert_lock_upgraded();
+ release_waiters();
+ }
+
+ bool try_unlock_upgrade_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count()==1)
+ {
+ state.unlock_upgrade();
+ state.lock();
+ state.assert_locked();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_upgrade_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_upgrade_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ if (//state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| ! state.upgrade // this should be removed once the assertion work
+ || state.get_shared_count() != 1)
+ {
+ for (;;)
+ {
+ //cv_status status = shared_cond.wait_until(lk,abs_time);
+ cv_status status = upgrade_cond.wait_until(lk,abs_time);
+ if (//!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade // this should be removed once the assertion work
+ && state.get_shared_count() == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.unlock_upgrade();
+ state.lock();
+ return true;
+ }
+#endif
+
+ // Shared <-> Exclusive
+ void unlock_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_locked();
+ state.unlock();
+ state.lock_shared();
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //!state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: why this is needed?
+ //&& ! state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ && state.get_shared_count()==1)
+ {
+ state.unlock_shared();
+ state.lock();
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if ( // !state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ //|| state.upgrade // Fixme: why this is needed if state.get_shared_count()==1?
+ || state.get_shared_count() != 1)
+ {
+ for (;;)
+ {
+ cv_status status = shared_cond.wait_until(lk,abs_time);
+ if ( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ //&& ! state.upgrade
+ && state.get_shared_count() == 1)
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ state.unlock_shared();
+ state.lock();
+ state.upgrade=false; // Is this absolutely needed?
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
+ return true;
+ }
+#endif
+#endif
+
+ // Shared <-> Upgrade
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_upgraded();
+ //state.unlock_upgrade();
+ //state.lock_shared(); // less efficient
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false; // Is this absolutely needed?
+ release_waiters();
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock_upgrade()
+ {
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ && ! state.upgrade
+ )
+ {
+ state.upgrade=true;
+ return true;
+ }
+ return false;
+ }
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Rep, class Period>
+ bool
+ try_unlock_shared_and_lock_upgrade_for(
+ const chrono::duration<Rep, Period>& rel_time)
+ {
+ return try_unlock_shared_and_lock_upgrade_until(
+ chrono::steady_clock::now() + rel_time);
+ }
+ template <class Clock, class Duration>
+ bool
+ 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;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.assert_lock_shared();
+ if( //state.exclusive // this should be removed once the assertion work
+ state.exclusive_waiting_blocked // Fixme: is this needed?
+ || state.upgrade
+ )
+ {
+ for (;;)
+ {
+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
+ if( //! state.exclusive // this should be removed once the assertion work
+ ! state.exclusive_waiting_blocked // Fixme: is this needed?
+ && ! state.upgrade
+ )
+ break;
+ if(status == cv_status::timeout)
+ return false;
+ }
+ }
+ //state.unlock_shared();
+ //state.lock_upgrade(); // less efficient
+ state.upgrade=true;
+ return true;
+ }
+#endif
+#endif
+ };
+
+ typedef shared_mutex upgrade_mutex;
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/thread_data.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/thread_data.hpp
new file mode 100644
index 00000000000..801f470b463
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/thread_data.hpp
@@ -0,0 +1,283 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// 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)
+// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/exceptions.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/assert.hpp>
+#ifdef BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/system_clocks.hpp>
+#endif
+
+#include <map>
+#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>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ class thread_attributes {
+ public:
+ thread_attributes() BOOST_NOEXCEPT {
+ int res = pthread_attr_init(&val_);
+ BOOST_VERIFY(!res && "pthread_attr_init failed");
+ }
+ ~thread_attributes() {
+ int res = pthread_attr_destroy(&val_);
+ BOOST_VERIFY(!res && "pthread_attr_destroy failed");
+ }
+ // stack
+ void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
+ if (size==0) return;
+ std::size_t page_size = getpagesize();
+#ifdef PTHREAD_STACK_MIN
+ if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
+#endif
+ size = ((size+page_size-1)/page_size)*page_size;
+ int res = pthread_attr_setstacksize(&val_, size);
+ BOOST_VERIFY(!res && "pthread_attr_setstacksize failed");
+ }
+
+ std::size_t get_stack_size() const BOOST_NOEXCEPT {
+ std::size_t size;
+ int res = pthread_attr_getstacksize(&val_, &size);
+ BOOST_VERIFY(!res && "pthread_attr_getstacksize failed");
+ return size;
+ }
+#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
+
+ typedef pthread_attr_t native_handle_type;
+ native_handle_type* native_handle() BOOST_NOEXCEPT {
+ return &val_;
+ }
+ const native_handle_type* native_handle() const BOOST_NOEXCEPT {
+ return &val_;
+ }
+
+ private:
+ pthread_attr_t val_;
+ };
+
+ class thread;
+
+ namespace detail
+ {
+ struct shared_state_base;
+ struct tss_cleanup_function;
+ struct thread_exit_callback_node;
+ struct tss_data_node
+ {
+ boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+ void* value;
+
+ tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
+ void* value_):
+ func(func_),value(value_)
+ {}
+ };
+
+ struct thread_data_base;
+ typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
+
+ struct BOOST_THREAD_DECL thread_data_base:
+ enable_shared_from_this<thread_data_base>
+ {
+ thread_data_ptr self;
+ pthread_t thread_handle;
+ boost::mutex data_mutex;
+ boost::condition_variable done_condition;
+ boost::mutex sleep_mutex;
+ boost::condition_variable sleep_condition;
+ bool done;
+ bool join_started;
+ bool joined;
+ boost::detail::thread_exit_callback_node* thread_exit_callbacks;
+ std::map<void const*,boost::detail::tss_data_node> tss_data;
+
+ pthread_mutex_t* cond_mutex;
+ pthread_cond_t* current_cond;
+ typedef std::vector<std::pair<condition_variable*, mutex*>
+ //, hidden_allocator<std::pair<condition_variable*, mutex*> >
+ > 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),
+ cond_mutex(0),
+ current_cond(0),
+ 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;
+ 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;
+ pthread_mutex_t* m;
+ bool set;
+
+ void check_for_interruption()
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+ if(thread_info->interrupt_requested)
+ {
+ thread_info->interrupt_requested=false;
+ throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected
+ }
+#endif
+ }
+
+ void operator=(interruption_checker&);
+ public:
+ explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
+ thread_info(detail::get_current_thread_data()),m(cond_mutex),
+ set(thread_info && thread_info->interrupt_enabled)
+ {
+ if(set)
+ {
+ lock_guard<mutex> guard(thread_info->data_mutex);
+ check_for_interruption();
+ thread_info->cond_mutex=cond_mutex;
+ thread_info->current_cond=cond;
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ else
+ {
+ BOOST_VERIFY(!pthread_mutex_lock(m));
+ }
+ }
+ ~interruption_checker()
+ {
+ if(set)
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ lock_guard<mutex> guard(thread_info->data_mutex);
+ thread_info->cond_mutex=NULL;
+ thread_info->current_cond=NULL;
+ }
+ else
+ {
+ BOOST_VERIFY(!pthread_mutex_unlock(m));
+ }
+ }
+ };
+#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)
+ {
+ 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<>
+#endif
+ inline void sleep(system_time const& abs_time)
+ {
+ return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
+ }
+
+ template<typename TimeDuration>
+ inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
+ {
+ this_thread::sleep(get_system_time()+rel_time);
+ }
+#endif // BOOST_THREAD_USES_DATETIME
+ } // this_thread
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/thread_heap_alloc.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/thread_heap_alloc.hpp
new file mode 100644
index 00000000000..7828318f05f
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/thread_heap_alloc.hpp
@@ -0,0 +1,242 @@
+// 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)
+// (C) Copyright 2008 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_PTHREAD_HPP
+#define THREAD_HEAP_ALLOC_PTHREAD_HPP
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+ namespace detail
+ {
+ template<typename T>
+ inline T* heap_new()
+ {
+ return new T();
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename T,typename A1>
+ inline T* heap_new(A1&& a1)
+ {
+ return new T(static_cast<A1&&>(a1));
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1&& a1,A2&& a2)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3));
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+ {
+ return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+ }
+#else
+ template<typename T,typename A1>
+ inline T* heap_new_impl(A1 a1)
+ {
+ return new T(a1);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new_impl(A1 a1,A2 a2)
+ {
+ return new T(a1,a2);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
+ {
+ return new T(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
+ {
+ return new T(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1>
+ inline T* heap_new(A1 const& a1)
+ {
+ return heap_new_impl<T,A1 const&>(a1);
+ }
+ template<typename T,typename A1>
+ inline T* heap_new(A1& a1)
+ {
+ return heap_new_impl<T,A1&>(a1);
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1&,A2&>(a1,a2);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+
+#endif
+ template<typename T>
+ inline void heap_delete(T* data)
+ {
+ delete data;
+ }
+
+ template<typename T>
+ struct do_heap_delete
+ {
+ void operator()(T* data) const
+ {
+ detail::heap_delete(data);
+ }
+ };
+ }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/thread/pthread/timespec.hpp b/src/third_party/boost-1.56.0/boost/thread/pthread/timespec.hpp
new file mode 100644
index 00000000000..82f50f6ca74
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/thread/pthread/timespec.hpp
@@ -0,0 +1,120 @@
+#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+// (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
+ {
+#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>
+
+#endif