diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread')
8 files changed, 965 insertions, 201 deletions
| diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp index 9c5bee2..aa71007 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp @@ -4,11 +4,17 @@  // 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 -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" -#include "thread_data.hpp" -#include "condition_variable_fwd.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#include <boost/thread/pthread/thread_data.hpp> +#include <boost/thread/pthread/condition_variable_fwd.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #include <boost/config/abi_prefix.hpp> @@ -18,14 +24,14 @@ namespace boost      {          void BOOST_THREAD_DECL interruption_point();      } -     +      namespace thread_cv_detail      {          template<typename MutexType>          struct lock_on_exit          {              MutexType* m; -             +              lock_on_exit():                  m(0)              {} @@ -44,66 +50,82 @@ namespace boost             }          };      } -     +      inline void condition_variable::wait(unique_lock<mutex>& m)      { -        thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; -        detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -        guard.activate(m); -        int const res=pthread_cond_wait(&cond,&internal_mutex); -        BOOST_ASSERT(!res); +        int res=0; +        { +            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); +        }          this_thread::interruption_point(); +        if(res) +        { +            boost::throw_exception(condition_error(res, "boost:: condition_variable constructor failed in pthread_cond_wait")); +        }      } -    inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) +    inline bool condition_variable::do_timed_wait( +                unique_lock<mutex>& m, +                struct timespec const &timeout)      { +        if (!m.owns_lock()) +            boost::throw_exception(condition_error(EPERM, "condition_variable do_timed_wait: mutex not locked")); +          thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; -        detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -        guard.activate(m); -        struct timespec const timeout=detail::get_timespec(wait_until); -        int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +        int cond_res; +        { +            detail::interruption_checker check_for_interruption(&internal_mutex,&cond); +            guard.activate(m); +            cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +        }          this_thread::interruption_point();          if(cond_res==ETIMEDOUT)          {              return false;          } -        BOOST_ASSERT(!cond_res); +        if(cond_res) +        { +            boost::throw_exception(condition_error(cond_res, "condition_variable failed in pthread_cond_timedwait")); +        }          return true;      } -    inline void condition_variable::notify_one() +    inline void condition_variable::notify_one() BOOST_NOEXCEPT      {          boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);          BOOST_VERIFY(!pthread_cond_signal(&cond));      } -         -    inline void condition_variable::notify_all() + +    inline void condition_variable::notify_all() BOOST_NOEXCEPT      {          boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);          BOOST_VERIFY(!pthread_cond_broadcast(&cond));      } -     +      class condition_variable_any      {          pthread_mutex_t internal_mutex;          pthread_cond_t cond; -        condition_variable_any(condition_variable_any&); -        condition_variable_any& operator=(condition_variable_any&); -      public: +        BOOST_THREAD_NO_COPYABLE(condition_variable_any)          condition_variable_any()          {              int const res=pthread_mutex_init(&internal_mutex,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "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()); +                boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_cond_init"));              }          }          ~condition_variable_any() @@ -111,7 +133,7 @@ namespace boost              BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));              BOOST_VERIFY(!pthread_cond_destroy(&cond));          } -         +          template<typename lock_type>          void wait(lock_type& m)          { @@ -121,11 +143,11 @@ namespace boost                  detail::interruption_checker check_for_interruption(&internal_mutex,&cond);                  guard.activate(m);                  res=pthread_cond_wait(&cond,&internal_mutex); -                this_thread::interruption_point();              } +            this_thread::interruption_point();              if(res)              { -                boost::throw_exception(condition_error()); +                boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_wait"));              }          } @@ -134,28 +156,12 @@ namespace boost          {              while(!pred()) wait(m);          } -         +          template<typename lock_type>          bool timed_wait(lock_type& m,boost::system_time const& wait_until)          {              struct timespec const timeout=detail::get_timespec(wait_until); -            int res=0; -            { -                thread_cv_detail::lock_on_exit<lock_type> guard; -                detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -                guard.activate(m); -                res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); -                this_thread::interruption_point(); -            } -            if(res==ETIMEDOUT) -            { -                return false; -            } -            if(res) -            { -                boost::throw_exception(condition_error()); -            } -            return true; +            return do_timed_wait(m, timeout);          }          template<typename lock_type>          bool timed_wait(lock_type& m,xtime const& wait_until) @@ -192,17 +198,134 @@ namespace boost              return timed_wait(m,get_system_time()+wait_duration,pred);          } -        void notify_one() +#ifdef BOOST_THREAD_USES_CHRONO +        template <class lock_type,class Duration> +        cv_status +        wait_until( +                lock_type& lock, +                const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          wait_until(lock, +                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +          return system_clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class lock_type, class Clock, class Duration> +        cv_status +        wait_until( +                lock_type& lock, +                const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          system_clock::time_point     s_now = system_clock::now(); +          typename Clock::time_point  c_now = Clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now)); +          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; +        } + +        template <class lock_type, class Clock, class Duration, class Predicate> +        bool +        wait_until( +                lock_type& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } + + +        template <class lock_type, class Rep, class Period> +        cv_status +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          system_clock::time_point s_now = system_clock::now(); +          steady_clock::time_point c_now = steady_clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(d)); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; + +        } + + +        template <class lock_type, class Rep, class Period, class Predicate> +        bool +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +          while (!pred()) +          { +              if (wait_for(lock, d) == cv_status::timeout) +                  return pred(); +          } +          return true; +        } + +        template <class lock_type> +        inline void 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); +        } +#endif + +        void notify_one() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         -        void notify_all() + +        void notify_all() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);              BOOST_VERIFY(!pthread_cond_broadcast(&cond));          } +    private: // used by boost::thread::try_join_until + +        template <class lock_type> +        inline bool do_timed_wait( +          lock_type& m, +          struct timespec const &timeout) +        { +          int res=0; +          { +              thread_cv_detail::lock_on_exit<lock_type> guard; +              detail::interruption_checker check_for_interruption(&internal_mutex,&cond); +              guard.activate(m); +              res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +          } +          this_thread::interruption_point(); +          if(res==ETIMEDOUT) +          { +              return false; +          } +          if(res) +          { +              boost::throw_exception(condition_error(res, "condition_variable_any 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 365f511..dbb3892 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp @@ -4,47 +4,57 @@  // 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  #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/thread_time.hpp>  #include <boost/thread/xtime.hpp> - +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp> +#include <boost/date_time/posix_time/posix_time_duration.hpp>  #include <boost/config/abi_prefix.hpp>  namespace boost  { +      class condition_variable      {      private:          pthread_mutex_t internal_mutex;          pthread_cond_t cond; -         -        condition_variable(condition_variable&); -        condition_variable& operator=(condition_variable&);      public: +      BOOST_THREAD_NO_COPYABLE(condition_variable)          condition_variable()          {              int const res=pthread_mutex_init(&internal_mutex,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: condition_variable constructor 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()); +                boost::throw_exception(thread_resource_error(res2, "boost:: condition_variable constructor failed in pthread_cond_init"));              }          }          ~condition_variable()          {              BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); -            BOOST_VERIFY(!pthread_cond_destroy(&cond)); +            int ret; +            do { +              ret = pthread_cond_destroy(&cond); +            } while (ret == EINTR); +            BOOST_VERIFY(!ret);          }          void wait(unique_lock<mutex>& m); @@ -55,21 +65,38 @@ namespace boost              while(!pred()) wait(m);          } -        inline bool timed_wait(unique_lock<mutex>& m, -                               boost::system_time const& wait_until); -        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until) + +        inline bool timed_wait( +            unique_lock<mutex>& m, +            boost::system_time const& wait_until) +        { +#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); +#else +            struct timespec const timeout=detail::get_timespec(wait_until); +            return do_timed_wait(m, timeout); +#endif +        } +        bool timed_wait( +            unique_lock<mutex>& m, +            xtime const& wait_until)          {              return timed_wait(m,system_time(wait_until));          }          template<typename duration_type> -        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) +        bool timed_wait( +            unique_lock<mutex>& m, +            duration_type const& wait_duration)          {              return timed_wait(m,get_system_time()+wait_duration);          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            boost::system_time const& wait_until,predicate_type pred)          {              while (!pred())              { @@ -80,28 +107,133 @@ namespace boost          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            xtime const& wait_until,predicate_type pred)          {              return timed_wait(m,system_time(wait_until),pred);          }          template<typename duration_type,typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            duration_type const& wait_duration,predicate_type pred)          {              return timed_wait(m,get_system_time()+wait_duration,pred);          } +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Duration> +        cv_status +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          wait_until(lock, +                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +          return system_clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class Clock, class Duration> +        cv_status +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          system_clock::time_point     s_now = system_clock::now(); +          typename Clock::time_point  c_now = Clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now)); +          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; +        } + +        template <class Clock, class Duration, class Predicate> +        bool +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } + + +        template <class Rep, class Period> +        cv_status +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          system_clock::time_point s_now = system_clock::now(); +          steady_clock::time_point c_now = steady_clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(d)); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; + +        } + + +        template <class Rep, class Period, class Predicate> +        bool +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +          while (!pred()) +          { +              if (wait_for(lock, d) == cv_status::timeout) +                  return pred(); +          } +          return true; +        } +#endif + +#define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE          typedef pthread_cond_t* native_handle_type;          native_handle_type native_handle()          {              return &cond;          } -        void notify_one(); -        void notify_all(); +        void notify_one() BOOST_NOEXCEPT; +        void notify_all() BOOST_NOEXCEPT; + +#ifdef BOOST_THREAD_USES_CHRONO +        inline void 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); +        } +#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);  } +  #include <boost/config/abi_suffix.hpp>  #endif diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp index 2a326d7..2c5af92 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp @@ -1,12 +1,12 @@  #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP  #define BOOST_THREAD_PTHREAD_MUTEX_HPP  // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  // Distributed under the Boost Software License, Version 1.0. (See  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  #include <pthread.h> -#include <boost/utility.hpp>  #include <boost/throw_exception.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -14,11 +14,16 @@  #include <boost/thread/xtime.hpp>  #include <boost/assert.hpp>  #include <errno.h> -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #ifdef _POSIX_TIMEOUTS -#if _POSIX_TIMEOUTS >= 0 +#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L  #define BOOST_PTHREAD_HAS_TIMEDLOCK  #endif  #endif @@ -30,48 +35,70 @@ namespace boost      class mutex      {      private: -        mutex(mutex const&); -        mutex& operator=(mutex const&);                  pthread_mutex_t m;      public: +        BOOST_THREAD_NO_COPYABLE(mutex) +          mutex()          {              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));              }          }          ~mutex()          { -            BOOST_VERIFY(!pthread_mutex_destroy(&m)); +            int ret; +            do +            { +                ret = pthread_mutex_destroy(&m); +            } while (ret == EINTR);          } -         +          void lock()          { -            int const res=pthread_mutex_lock(&m); -            if(res) +            int res; +            do +            { +                res = pthread_mutex_lock(&m); +            } while (res == EINTR); +            if (res)              { -                boost::throw_exception(lock_error(res)); +                boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));              }          }          void unlock()          { -            BOOST_VERIFY(!pthread_mutex_unlock(&m)); +            int ret; +            do +            { +                ret = pthread_mutex_unlock(&m); +            } while (ret == EINTR); +            BOOST_VERIFY(!ret);          } -         +          bool try_lock()          { -            int const res=pthread_mutex_trylock(&m); +            int res; +            do +            { +                res = pthread_mutex_trylock(&m); +            } while (res == EINTR);              if(res && (res!=EBUSY))              { -                boost::throw_exception(lock_error(res)); +                // The following throw_exception has been replaced by an assertion and just return false, +                // as this is an internal error and the user can do nothing with the exception. +                //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock")); +                BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock"); +                return false;              } -             +              return !res;          } +#define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE          typedef pthread_mutex_t* native_handle_type;          native_handle_type native_handle()          { @@ -87,28 +114,26 @@ namespace boost      class timed_mutex      {      private: -        timed_mutex(timed_mutex const&); -        timed_mutex& operator=(timed_mutex const&);         -    private:          pthread_mutex_t m;  #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK          pthread_cond_t cond;          bool is_locked;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(timed_mutex)          timed_mutex()          {              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));              }  #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;  #endif @@ -141,26 +166,23 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         +          bool try_lock()          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } -        bool timed_lock(system_time const & abs_time) -        { -            struct timespec const timeout=detail::get_timespec(abs_time); -            int const res=pthread_mutex_timedlock(&m,&timeout); -            BOOST_ASSERT(!res || res==ETIMEDOUT); -            return !res; -        } -        typedef pthread_mutex_t* native_handle_type; -        native_handle_type native_handle() + +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            return &m; +          int const res=pthread_mutex_timedlock(&m,&timeout); +          BOOST_ASSERT(!res || res==ETIMEDOUT); +          return !res;          } +    public:  #else          void lock() @@ -179,7 +201,7 @@ namespace boost              is_locked=false;              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         +          bool try_lock()          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); @@ -191,9 +213,9 @@ namespace boost              return true;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              while(is_locked)              { @@ -207,8 +229,55 @@ namespace boost              is_locked=true;              return true;          } +    public:  #endif +        bool timed_lock(system_time const & abs_time) +        { +            struct timespec const ts=detail::get_timespec(abs_time); +            return do_try_lock_until(ts); +        } + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          system_clock::time_point     s_now = system_clock::now(); +          typename Clock::time_point  c_now = Clock::now(); +          return try_lock_until(s_now + ceil<nanoseconds>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +        } +        bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) +        { +          using namespace chrono; +          nanoseconds d = tp.time_since_epoch(); +          timespec ts; +          seconds s = duration_cast<seconds>(d); +          ts.tv_sec = static_cast<long>(s.count()); +          ts.tv_nsec = static_cast<long>((d - s).count()); +          return do_try_lock_until(ts); +        } +#endif + +#define BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE +        typedef pthread_mutex_t* native_handle_type; +        native_handle_type native_handle() +        { +            return &m; +        } +          typedef unique_lock<timed_mutex> scoped_timed_lock;          typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;          typedef scoped_timed_lock scoped_lock; diff --git a/3rdParty/Boost/src/boost/thread/pthread/once.hpp b/3rdParty/Boost/src/boost/thread/pthread/once.hpp index 6321aa2..02c2732 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/once.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/once.hpp @@ -3,53 +3,86 @@  //  once.hpp  // -//  (C) Copyright 2007-8 Anthony Williams  +//  (C) Copyright 2007-8 Anthony Williams +//  (C) Copyright 2011-2012 Vicente J. Botet Escriba  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at  //  http://www.boost.org/LICENSE_1_0.txt)  #include <boost/thread/detail/config.hpp> -#include <boost/config.hpp> -#include <pthread.h> -#include <boost/assert.hpp> -#include "pthread_mutex_scoped_lock.hpp"  #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> -#include <boost/cstdint.hpp> +#include <boost/thread/detail/delete.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/assert.hpp>  #include <boost/config/abi_prefix.hpp> +#include <boost/cstdint.hpp> +#include <pthread.h> +#include <csignal> +  namespace boost  { +#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 +    #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0) +//#endif +  } + +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + +  struct once_flag +  { +      BOOST_THREAD_NO_COPYABLE(once_flag) +      BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT +        : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE) +      {} +  private: +      volatile thread_detail::uintmax_atomic_t epoch; +      template<typename Function> +      friend +      void call_once(once_flag& flag,Function f); +  }; + +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 +      struct once_flag      { -        boost::uintmax_t epoch; +      volatile thread_detail::uintmax_atomic_t epoch;      }; +#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} +#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 +      namespace detail      { -        BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch(); -        BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch; +        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 extern pthread_mutex_t once_epoch_mutex;          BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;      } -     -#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 -#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} -      // 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)      { -        static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE; -        static boost::uintmax_t const being_initialized=uninitialized_flag+1; -        boost::uintmax_t const epoch=flag.epoch; -        boost::uintmax_t& this_thread_epoch=detail::get_once_per_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(); +          if(epoch<this_thread_epoch)          {              pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex); @@ -59,21 +92,18 @@ namespace boost                  if(flag.epoch==uninitialized_flag)                  {                      flag.epoch=being_initialized; -#ifndef BOOST_NO_EXCEPTIONS -                    try +                    BOOST_TRY                      { -#endif                          pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);                          f(); -#ifndef BOOST_NO_EXCEPTIONS                      } -                    catch(...) +                    BOOST_CATCH (...)                      {                          flag.epoch=uninitialized_flag;                          BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); -                        throw; +                        BOOST_RETHROW                      } -#endif +                    BOOST_CATCH_END                      flag.epoch=--detail::once_global_epoch;                      BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));                  } diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp index 4158a57..2a6bc7d 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp @@ -1,12 +1,12 @@  #ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP  #define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP  // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  // Distributed under the Boost Software License, Version 1.0. (See  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  #include <pthread.h> -#include <boost/utility.hpp>  #include <boost/throw_exception.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -17,8 +17,13 @@  #endif  #include <boost/date_time/posix_time/conversion.hpp>  #include <errno.h> -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #ifdef _POSIX_TIMEOUTS  #if _POSIX_TIMEOUTS >= 0 @@ -26,7 +31,7 @@  #endif  #endif -#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK) +#if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)  #define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK  #endif @@ -37,51 +42,50 @@ namespace boost      class recursive_mutex      {      private: -        recursive_mutex(recursive_mutex const&); -        recursive_mutex& operator=(recursive_mutex const&);                  pthread_mutex_t m; -#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE          pthread_cond_t cond;          bool is_locked;          pthread_t owner;          unsigned count;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(recursive_mutex)          recursive_mutex()          { -#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE              pthread_mutexattr_t attr; -             +              int const init_attr_res=pthread_mutexattr_init(&attr);              if(init_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_init"));              }              int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);              if(set_attr_res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype"));              } -             +              int const res=pthread_mutex_init(&m,&attr);              if(res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));              }              BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));  #else              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;              count=0; @@ -90,12 +94,12 @@ namespace boost          ~recursive_mutex()          {              BOOST_VERIFY(!pthread_mutex_destroy(&m)); -#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE              BOOST_VERIFY(!pthread_cond_destroy(&cond));  #endif          } -#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE          void lock()          {              BOOST_VERIFY(!pthread_mutex_lock(&m)); @@ -105,13 +109,14 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         -        bool try_lock() + +        bool try_lock() BOOST_NOEXCEPT          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } +#define BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE          typedef pthread_mutex_t* native_handle_type;          native_handle_type native_handle()          { @@ -127,7 +132,7 @@ namespace boost                  ++count;                  return;              } -             +              while(is_locked)              {                  BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); @@ -146,7 +151,7 @@ namespace boost              }              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         +          bool try_lock()          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); @@ -171,9 +176,6 @@ namespace boost      class recursive_timed_mutex      {      private: -        recursive_timed_mutex(recursive_timed_mutex const&); -        recursive_timed_mutex& operator=(recursive_timed_mutex const&);         -    private:          pthread_mutex_t m;  #ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK          pthread_cond_t cond; @@ -182,40 +184,41 @@ namespace boost          unsigned count;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)          recursive_timed_mutex()          {  #ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK              pthread_mutexattr_t attr; -             +              int const init_attr_res=pthread_mutexattr_init(&attr);              if(init_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_init"));              }              int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);              if(set_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype"));              } -             +              int const res=pthread_mutex_init(&m,&attr);              if(res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));              }              BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));  #else              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;              count=0; @@ -245,26 +248,22 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         +          bool try_lock()          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              int const res=pthread_mutex_timedlock(&m,&timeout);              BOOST_ASSERT(!res || res==ETIMEDOUT);              return !res;          } -        typedef pthread_mutex_t* native_handle_type; -        native_handle_type native_handle() -        { -            return &m; -        } +    public:  #else          void lock() @@ -275,7 +274,7 @@ namespace boost                  ++count;                  return;              } -             +              while(is_locked)              {                  BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); @@ -294,8 +293,8 @@ namespace boost              }              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         -        bool try_lock() + +        bool try_lock() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              if(is_locked && !pthread_equal(owner,pthread_self())) @@ -308,9 +307,9 @@ namespace boost              return true;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              if(is_locked && pthread_equal(owner,pthread_self()))              { @@ -331,8 +330,56 @@ namespace boost              owner=pthread_self();              return true;          } +    public: +  #endif +        bool timed_lock(system_time const & abs_time) +        { +            struct timespec const ts=detail::get_timespec(abs_time); +            return do_try_lock_until(ts); +        } + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          system_clock::time_point     s_now = system_clock::now(); +          typename Clock::time_point  c_now = Clock::now(); +          return try_lock_until(s_now + ceil<nanoseconds>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +        } +        bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) +        { +          using namespace chrono; +          nanoseconds d = tp.time_since_epoch(); +          timespec ts; +          seconds s = duration_cast<seconds>(d); +          ts.tv_sec = static_cast<long>(s.count()); +          ts.tv_nsec = static_cast<long>((d - s).count()); +          return do_try_lock_until(ts); +        } +#endif + +#define BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE +        typedef pthread_mutex_t* native_handle_type; +        native_handle_type native_handle() +        { +            return &m; +        } +          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; diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index bc26282..cf45188 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -2,6 +2,7 @@  #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP  //  (C) Copyright 2006-8 Anthony Williams +//  (C) Copyright 2012 Vicente J. Botet Escriba  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at @@ -12,6 +13,11 @@  #include <boost/thread/mutex.hpp>  #include <boost/thread/condition_variable.hpp>  #include <boost/thread/detail/thread_interruption.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #include <boost/config/abi_prefix.hpp> @@ -27,7 +33,7 @@ namespace boost              bool upgrade;              bool exclusive_waiting_blocked;          }; -         +          state_data state; @@ -41,9 +47,10 @@ namespace boost              exclusive_cond.notify_one();              shared_cond.notify_all();          } -              public: +        BOOST_THREAD_NO_COPYABLE(shared_mutex) +          shared_mutex()          {              state_data state_={0,0,0,0}; @@ -58,7 +65,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.exclusive || state.exclusive_waiting_blocked)              {                  shared_cond.wait(lk); @@ -69,7 +76,7 @@ namespace boost          bool try_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); -                 +              if(state.exclusive || state.exclusive_waiting_blocked)              {                  return false; @@ -85,7 +92,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.exclusive || state.exclusive_waiting_blocked)              {                  if(!shared_cond.timed_wait(lk,timeout)) @@ -102,12 +109,34 @@ namespace boost          {              return timed_lock_shared(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_shared_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          while(state.exclusive || state.exclusive_waiting_blocked) +          { +              if(cv_status::timeout==shared_cond.wait_until(lk,abs_time)) +              { +                  return false; +              } +          } +          ++state.shared_count; +          return true; +        } +#endif          void unlock_shared()          {              boost::mutex::scoped_lock lk(state_change);              bool const last_reader=!--state.shared_count; -                 +              if(last_reader)              {                  if(state.upgrade) @@ -128,7 +157,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.shared_count || state.exclusive)              {                  state.exclusive_waiting_blocked=true; @@ -150,7 +179,7 @@ namespace boost                      if(state.shared_count || state.exclusive)                      {                          state.exclusive_waiting_blocked=false; -                        exclusive_cond.notify_one(); +                        release_waiters();                          return false;                      }                      break; @@ -166,10 +195,41 @@ namespace boost              return timed_lock(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); + +          while(state.shared_count || state.exclusive) +          { +              state.exclusive_waiting_blocked=true; +              if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time)) +              { +                  if(state.shared_count || state.exclusive) +                  { +                      state.exclusive_waiting_blocked=false; +                      release_waiters(); +                      return false; +                  } +                  break; +              } +          } +          state.exclusive=true; +          return true; +        } +#endif +          bool try_lock()          {              boost::mutex::scoped_lock lk(state_change); -                 +              if(state.shared_count || state.exclusive)              {                  return false; @@ -179,7 +239,7 @@ namespace boost                  state.exclusive=true;                  return true;              } -                 +          }          void unlock() @@ -228,6 +288,33 @@ namespace boost              return timed_lock_upgrade(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) +          { +              if(cv_status::timeout == shared_cond.wait_until(lk,abs_time)) +              { +                  if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) +                  { +                      return false; +                  } +                  break; +              } +          } +          ++state.shared_count; +          state.upgrade=true; +          return true; +        } +#endif          bool try_lock_upgrade()          {              boost::mutex::scoped_lock lk(state_change); @@ -248,14 +335,17 @@ namespace boost              boost::mutex::scoped_lock lk(state_change);              state.upgrade=false;              bool const last_reader=!--state.shared_count; -                 +              if(last_reader)              {                  state.exclusive_waiting_blocked=false;                  release_waiters(); +            } else { +              shared_cond.notify_all();              }          } +        // Upgrade <-> Exclusive          void unlock_upgrade_and_lock()          {              boost::this_thread::disable_interruption do_not_disturb; @@ -278,7 +368,58 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } -         + +        bool try_unlock_upgrade_and_lock() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && state.upgrade +              && state.shared_count==1) +          { +            state.shared_count=0; +            state.exclusive=true; +            state.upgrade=false; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool +        try_unlock_upgrade_and_lock_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_upgrade_and_lock_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool +        try_unlock_upgrade_and_lock_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if (state.shared_count != 1) +          { +              for (;;) +              { +                cv_status status = shared_cond.wait_until(lk,abs_time); +                if (state.shared_count == 1) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=false; +          state.exclusive=true; +          state.exclusive_waiting_blocked=false; +          state.shared_count=0; +          return true; +        } +#endif + +        // Shared <-> Exclusive          void unlock_and_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); @@ -287,7 +428,59 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } -         + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        bool try_unlock_shared_and_lock() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && !state.upgrade +              && state.shared_count==1) +          { +            state.shared_count=0; +            state.exclusive=true; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +            bool +            try_unlock_shared_and_lock_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_shared_and_lock_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +            bool +            try_unlock_shared_and_lock_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if (state.shared_count != 1) +          { +              for (;;) +              { +                cv_status status = shared_cond.wait_until(lk,abs_time); +                if (state.shared_count == 1) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=false; +          state.exclusive=true; +          state.exclusive_waiting_blocked=false; +          state.shared_count=0; +          return true; +        } +#endif +#endif + +        // Shared <-> Upgrade          void unlock_upgrade_and_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); @@ -295,7 +488,62 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        bool try_unlock_shared_and_lock_upgrade() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && !state.upgrade +              ) +          { +            state.upgrade=true; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +            bool +            try_unlock_shared_and_lock_upgrade_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_shared_and_lock_upgrade_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +            bool +            try_unlock_shared_and_lock_upgrade_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if(    state.exclusive +              || state.exclusive_waiting_blocked +              || state.upgrade +              ) +          { +              for (;;) +              { +                cv_status status = exclusive_cond.wait_until(lk,abs_time); +                if(    ! state.exclusive +                    && ! state.exclusive_waiting_blocked +                    && ! state.upgrade +                    ) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=true; +          return true; +        } +#endif +#endif      }; + +    typedef shared_mutex upgrade_mutex;  }  #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 1bee28b..db4e09f 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -4,24 +4,77 @@  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  // (C) Copyright 2007 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  #include <boost/thread/detail/config.hpp>  #include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.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/thread/mutex.hpp>  #include <boost/optional.hpp> -#include <pthread.h>  #include <boost/assert.hpp> -#include "condition_variable_fwd.hpp" +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif +  #include <map> +#include <vector> +#include <utility> + +#include <pthread.h> +#include <unistd.h>  #include <boost/config/abi_prefix.hpp>  namespace boost  { +    class thread_attributes { +    public: +        thread_attributes() BOOST_NOEXCEPT { +            int res = pthread_attr_init(&val_); +            BOOST_VERIFY(!res && "pthread_attr_init failed"); +        } +        ~thread_attributes() { +          int res = pthread_attr_destroy(&val_); +          BOOST_VERIFY(!res && "pthread_attr_destroy failed"); +        } +        // stack +        void set_stack_size(std::size_t size) BOOST_NOEXCEPT { +          if (size==0) return; +          std::size_t page_size = getpagesize(); +#ifdef PTHREAD_STACK_MIN +          if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN; +#endif +          size = ((size+page_size-1)/page_size)*page_size; +          int res = pthread_attr_setstacksize(&val_, size); +          BOOST_VERIFY(!res && "pthread_attr_setstacksize failed"); +        } + +        std::size_t get_stack_size() const BOOST_NOEXCEPT { +            std::size_t size; +            int res = pthread_attr_getstacksize(&val_, &size); +            BOOST_VERIFY(!res && "pthread_attr_getstacksize failed"); +            return size; +        } +#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE + +        typedef pthread_attr_t native_handle_type; +        native_handle_type* native_handle() BOOST_NOEXCEPT { +          return &val_; +        } +        const native_handle_type* native_handle() const BOOST_NOEXCEPT { +          return &val_; +        } + +    private: +        pthread_attr_t val_; +    }; +      class thread; -     +      namespace detail      {          struct tss_cleanup_function; @@ -39,7 +92,7 @@ namespace boost          struct thread_data_base;          typedef boost::shared_ptr<thread_data_base> thread_data_ptr; -         +          struct BOOST_THREAD_DECL thread_data_base:              enable_shared_from_this<thread_data_base>          { @@ -58,19 +111,28 @@ namespace boost              bool interrupt_requested;              pthread_mutex_t* cond_mutex;              pthread_cond_t* current_cond; +            typedef std::vector<std::pair<condition_variable*, mutex*> +            //, hidden_allocator<std::pair<condition_variable*, mutex*> > +            > notify_list_t; +            notify_list_t notify;              thread_data_base():                  done(false),join_started(false),joined(false),                  thread_exit_callbacks(0),                  interrupt_enabled(true),                  interrupt_requested(false), -                current_cond(0) +                current_cond(0), +                notify()              {}              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) +            { +              notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); +            }          };          BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); @@ -83,13 +145,15 @@ namespace boost              void check_for_interruption()              { +#ifndef BOOST_NO_EXCEPTIONS                  if(thread_info->interrupt_requested)                  {                      thread_info->interrupt_requested=false; -                    throw thread_interrupted(); +                    throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected                  } +#endif              } -             +              void operator=(interruption_checker&);          public:              explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): @@ -128,15 +192,66 @@ namespace boost      namespace this_thread      { -        void BOOST_THREAD_DECL yield(); -         -        void BOOST_THREAD_DECL sleep(system_time const& abs_time); -         +#ifdef BOOST_THREAD_USES_CHRONO +        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 +              } +            } +        } +#endif +        void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT; + +#ifdef __DECXXX +        /// Workaround of DECCXX issue of incorrect template substitution          template<typename TimeDuration>          inline void sleep(TimeDuration const& rel_time)          {              this_thread::sleep(get_system_time()+rel_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      }  } diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp index 737c298..7828318 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp @@ -17,7 +17,7 @@ namespace boost              return new T();          } -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES          template<typename T,typename A1>          inline T* heap_new(A1&& a1)          { @@ -72,7 +72,7 @@ namespace boost          {              return heap_new_impl<T,A1&>(a1);          } -         +          template<typename T,typename A1,typename A2>          inline T* heap_new(A1 const& a1,A2 const& a2)          { @@ -218,8 +218,8 @@ namespace boost          {              return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);          } -         -#endif         + +#endif          template<typename T>          inline void heap_delete(T* data)          { | 
 Swift
 Swift