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