diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread')
7 files changed, 207 insertions, 47 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp index 8e8f5b5..9c5bee2 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp @@ -3,7 +3,7 @@ // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2007-10 Anthony Williams #include "timespec.hpp" #include "pthread_mutex_scoped_lock.hpp" @@ -14,17 +14,55 @@ namespace boost { + namespace this_thread + { + void BOOST_THREAD_DECL interruption_point(); + } + + namespace thread_cv_detail + { + template<typename MutexType> + struct lock_on_exit + { + MutexType* m; + + lock_on_exit(): + m(0) + {} + + void activate(MutexType& m_) + { + m_.unlock(); + m=&m_; + } + ~lock_on_exit() + { + if(m) + { + m->lock(); + } + } + }; + } + inline void condition_variable::wait(unique_lock<mutex>& m) { - detail::interruption_checker check_for_interruption(&cond); - BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle())); + 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); + this_thread::interruption_point(); } inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) { - detail::interruption_checker check_for_interruption(&cond); + 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,m.mutex()->native_handle(),&timeout); + int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); + this_thread::interruption_point(); if(cond_res==ETIMEDOUT) { return false; @@ -35,11 +73,13 @@ namespace boost inline void condition_variable::notify_one() { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); BOOST_VERIFY(!pthread_cond_signal(&cond)); } inline void condition_variable::notify_all() { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); BOOST_VERIFY(!pthread_cond_broadcast(&cond)); } @@ -48,8 +88,8 @@ namespace boost pthread_mutex_t internal_mutex; pthread_cond_t cond; - condition_variable_any(condition_variable&); - condition_variable_any& operator=(condition_variable&); + condition_variable_any(condition_variable_any&); + condition_variable_any& operator=(condition_variable_any&); public: condition_variable_any() @@ -77,13 +117,11 @@ namespace boost { int res=0; { - detail::interruption_checker check_for_interruption(&cond); - { - boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); - m.unlock(); - res=pthread_cond_wait(&cond,&internal_mutex); - } - m.lock(); + thread_cv_detail::lock_on_exit<lock_type> guard; + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); + res=pthread_cond_wait(&cond,&internal_mutex); + this_thread::interruption_point(); } if(res) { @@ -103,13 +141,11 @@ namespace boost struct timespec const timeout=detail::get_timespec(wait_until); int res=0; { - detail::interruption_checker check_for_interruption(&cond); - { - boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); - m.unlock(); - res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); - } - m.lock(); + 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) { 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 59908f4..365f511 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp @@ -20,6 +20,7 @@ namespace boost class condition_variable { private: + pthread_mutex_t internal_mutex; pthread_cond_t cond; condition_variable(condition_variable&); @@ -28,14 +29,21 @@ namespace boost public: condition_variable() { - int const res=pthread_cond_init(&cond,NULL); + int const res=pthread_mutex_init(&internal_mutex,NULL); if(res) { boost::throw_exception(thread_resource_error()); } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); + boost::throw_exception(thread_resource_error()); + } } ~condition_variable() { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); BOOST_VERIFY(!pthread_cond_destroy(&cond)); } @@ -47,7 +55,8 @@ namespace boost while(!pred()) wait(m); } - bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until); + 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) { return timed_wait(m,system_time(wait_until)); diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp index 1f7f790..2a326d7 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp @@ -27,10 +27,11 @@ namespace boost { - class mutex: - boost::noncopyable + class mutex { private: + mutex(mutex const&); + mutex& operator=(mutex const&); pthread_mutex_t m; public: mutex() @@ -48,7 +49,11 @@ namespace boost void lock() { - BOOST_VERIFY(!pthread_mutex_lock(&m)); + int const res=pthread_mutex_lock(&m); + if(res) + { + boost::throw_exception(lock_error(res)); + } } void unlock() @@ -59,7 +64,11 @@ namespace boost bool try_lock() { int const res=pthread_mutex_trylock(&m); - BOOST_ASSERT(!res || res==EBUSY); + if(res && (res!=EBUSY)) + { + boost::throw_exception(lock_error(res)); + } + return !res; } @@ -75,10 +84,12 @@ namespace boost typedef mutex try_mutex; - class timed_mutex: - boost::noncopyable + 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; diff --git a/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp index 2407f91..cdbf8c6 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/pthread_mutex_scoped_lock.hpp @@ -18,15 +18,25 @@ namespace boost class pthread_mutex_scoped_lock { pthread_mutex_t* m; + bool locked; public: explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_): - m(m_) + m(m_),locked(true) { BOOST_VERIFY(!pthread_mutex_lock(m)); } - ~pthread_mutex_scoped_lock() + void unlock() { BOOST_VERIFY(!pthread_mutex_unlock(m)); + locked=false; + } + + ~pthread_mutex_scoped_lock() + { + if(locked) + { + unlock(); + } } }; diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp index ad3b7e1..4158a57 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp @@ -26,18 +26,30 @@ #endif #endif +#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK) +#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK +#endif + #include <boost/config/abi_prefix.hpp> namespace boost { - class recursive_mutex: - boost::noncopyable + 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 + pthread_cond_t cond; + bool is_locked; + pthread_t owner; + unsigned count; +#endif public: recursive_mutex() { +#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE pthread_mutexattr_t attr; int const init_attr_res=pthread_mutexattr_init(&attr); @@ -48,21 +60,42 @@ namespace boost 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()); } int const res=pthread_mutex_init(&m,&attr); if(res) { + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); boost::throw_exception(thread_resource_error()); } BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); +#else + int const res=pthread_mutex_init(&m,NULL); + if(res) + { + boost::throw_exception(thread_resource_error()); + } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + boost::throw_exception(thread_resource_error()); + } + is_locked=false; + count=0; +#endif } ~recursive_mutex() { BOOST_VERIFY(!pthread_mutex_destroy(&m)); +#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE + BOOST_VERIFY(!pthread_cond_destroy(&cond)); +#endif } - + +#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE void lock() { BOOST_VERIFY(!pthread_mutex_lock(&m)); @@ -79,25 +112,70 @@ namespace boost BOOST_ASSERT(!res || res==EBUSY); return !res; } - typedef pthread_mutex_t* native_handle_type; native_handle_type native_handle() { return &m; } +#else + void lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && pthread_equal(owner,pthread_self())) + { + ++count; + return; + } + + while(is_locked) + { + BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); + } + is_locked=true; + ++count; + owner=pthread_self(); + } + + void unlock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(!--count) + { + is_locked=false; + } + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + bool try_lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && !pthread_equal(owner,pthread_self())) + { + return false; + } + is_locked=true; + ++count; + owner=pthread_self(); + return true; + } + +#endif + typedef unique_lock<recursive_mutex> scoped_lock; typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; }; typedef recursive_mutex recursive_try_mutex; - class recursive_timed_mutex: - boost::noncopyable + 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_PTHREAD_HAS_TIMEDLOCK +#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK pthread_cond_t cond; bool is_locked; pthread_t owner; @@ -106,7 +184,7 @@ namespace boost public: recursive_timed_mutex() { -#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK pthread_mutexattr_t attr; int const init_attr_res=pthread_mutexattr_init(&attr); @@ -146,7 +224,7 @@ namespace boost ~recursive_timed_mutex() { BOOST_VERIFY(!pthread_mutex_destroy(&m)); -#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK BOOST_VERIFY(!pthread_cond_destroy(&cond)); #endif } @@ -157,7 +235,7 @@ namespace boost return timed_lock(get_system_time()+relative_time); } -#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK +#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK void lock() { BOOST_VERIFY(!pthread_mutex_lock(&m)); diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index 30440eb..bc26282 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -225,7 +225,7 @@ namespace boost template<typename TimeDuration> bool timed_lock_upgrade(TimeDuration const & relative_time) { - return timed_lock(get_system_time()+relative_time); + return timed_lock_upgrade(get_system_time()+relative_time); } bool try_lock_upgrade() diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 730c77c..1bee28b 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -12,6 +12,7 @@ #include <boost/thread/mutex.hpp> #include <boost/optional.hpp> #include <pthread.h> +#include <boost/assert.hpp> #include "condition_variable_fwd.hpp" #include <map> @@ -55,6 +56,7 @@ namespace boost 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; thread_data_base(): @@ -76,6 +78,8 @@ namespace boost class interruption_checker { thread_data_base* const thread_info; + pthread_mutex_t* m; + bool set; void check_for_interruption() { @@ -88,23 +92,35 @@ namespace boost void operator=(interruption_checker&); public: - explicit interruption_checker(pthread_cond_t* cond): - thread_info(detail::get_current_thread_data()) + explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): + thread_info(detail::get_current_thread_data()),m(cond_mutex), + set(thread_info && thread_info->interrupt_enabled) { - if(thread_info && thread_info->interrupt_enabled) + if(set) { lock_guard<mutex> guard(thread_info->data_mutex); check_for_interruption(); + thread_info->cond_mutex=cond_mutex; thread_info->current_cond=cond; + BOOST_VERIFY(!pthread_mutex_lock(m)); + } + else + { + BOOST_VERIFY(!pthread_mutex_lock(m)); } } ~interruption_checker() { - if(thread_info && thread_info->interrupt_enabled) + if(set) { + BOOST_VERIFY(!pthread_mutex_unlock(m)); lock_guard<mutex> guard(thread_info->data_mutex); + thread_info->cond_mutex=NULL; thread_info->current_cond=NULL; - check_for_interruption(); + } + else + { + BOOST_VERIFY(!pthread_mutex_unlock(m)); } } }; |