diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-04-11 18:19:17 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-04-11 19:20:07 (GMT) |
commit | 857e44c156a1dbefcb49bb5792c4384cebd8762a (patch) | |
tree | 11947fb81ad9c502627f1b2bb8f090fb8d53c107 /3rdParty/Boost/src/boost/thread | |
parent | 77d4eb7588e113beaa03f3347523b26adefdeb06 (diff) | |
download | swift-857e44c156a1dbefcb49bb5792c4384cebd8762a.zip swift-857e44c156a1dbefcb49bb5792c4384cebd8762a.tar.bz2 |
Updated Boost to 1.42.
Diffstat (limited to '3rdParty/Boost/src/boost/thread')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/move.hpp | 4 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/thread.hpp | 116 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/thread_group.hpp | 105 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp | 35 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/exceptions.hpp | 184 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/future.hpp | 1364 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/locks.hpp | 48 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp | 2 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp | 17 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/thread.hpp | 2 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/tss.hpp | 2 |
11 files changed, 1701 insertions, 178 deletions
diff --git a/3rdParty/Boost/src/boost/thread/detail/move.hpp b/3rdParty/Boost/src/boost/thread/detail/move.hpp index 044ecda..eb21107 100644 --- a/3rdParty/Boost/src/boost/thread/detail/move.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/move.hpp @@ -41,9 +41,9 @@ namespace boost #ifndef BOOST_NO_SFINAE template<typename T> - typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t) + typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t) { - return T(detail::thread_move_t<T>(t)); + return detail::thread_move_t<T>(t); } #endif diff --git a/3rdParty/Boost/src/boost/thread/detail/thread.hpp b/3rdParty/Boost/src/boost/thread/detail/thread.hpp index fbb895d..170801b 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/thread.hpp @@ -144,6 +144,9 @@ namespace boost struct dummy; #endif public: +#ifdef __SUNPRO_CC + thread(const volatile thread&); +#endif thread(); ~thread(); @@ -201,14 +204,21 @@ namespace boost thread_info=x->thread_info; x->thread_info.reset(); } - + +#ifdef __SUNPRO_CC + thread& operator=(thread x) + { + swap(x); + return *this; + } +#else thread& operator=(detail::thread_move_t<thread> x) { thread new_thread(x); swap(new_thread); return *this; } - +#endif operator detail::thread_move_t<thread>() { return move(); @@ -339,35 +349,14 @@ namespace boost return t; } #else - inline thread move(detail::thread_move_t<thread> t) + inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t) { - return thread(t); + return t; } #endif namespace this_thread { - class BOOST_THREAD_DECL disable_interruption - { - disable_interruption(const disable_interruption&); - disable_interruption& operator=(const disable_interruption&); - - bool interruption_was_enabled; - friend class restore_interruption; - public: - disable_interruption(); - ~disable_interruption(); - }; - - class BOOST_THREAD_DECL restore_interruption - { - restore_interruption(const restore_interruption&); - restore_interruption& operator=(const restore_interruption&); - public: - explicit restore_interruption(disable_interruption& d); - ~restore_interruption(); - }; - thread::id BOOST_THREAD_DECL get_id(); void BOOST_THREAD_DECL interruption_point(); @@ -487,83 +476,6 @@ namespace boost detail::add_thread_exit_function(thread_exit_func); } } - - class thread_group: - private noncopyable - { - public: - ~thread_group() - { - for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); - it!=end; - ++it) - { - delete *it; - } - } - - template<typename F> - thread* create_thread(F threadfunc) - { - boost::lock_guard<mutex> guard(m); - std::auto_ptr<thread> new_thread(new thread(threadfunc)); - threads.push_back(new_thread.get()); - return new_thread.release(); - } - - void add_thread(thread* thrd) - { - if(thrd) - { - boost::lock_guard<mutex> guard(m); - threads.push_back(thrd); - } - } - - void remove_thread(thread* thrd) - { - boost::lock_guard<mutex> guard(m); - std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd); - if(it!=threads.end()) - { - threads.erase(it); - } - } - - void join_all() - { - boost::lock_guard<mutex> guard(m); - - for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); - it!=end; - ++it) - { - (*it)->join(); - } - } - - void interrupt_all() - { - boost::lock_guard<mutex> guard(m); - - for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); - it!=end; - ++it) - { - (*it)->interrupt(); - } - } - - size_t size() const - { - boost::lock_guard<mutex> guard(m); - return threads.size(); - } - - private: - std::list<thread*> threads; - mutable mutex m; - }; } #ifdef BOOST_MSVC diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp new file mode 100644 index 0000000..823b92e --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/detail/thread_group.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP +#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// (C) Copyright 2007-9 Anthony Williams + +#include <list> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/mutex.hpp> + +#include <boost/config/abi_prefix.hpp> + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4251) +#endif + +namespace boost +{ + class thread_group: + private noncopyable + { + public: + ~thread_group() + { + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + delete *it; + } + } + + template<typename F> + thread* create_thread(F threadfunc) + { + boost::lock_guard<shared_mutex> guard(m); + std::auto_ptr<thread> new_thread(new thread(threadfunc)); + threads.push_back(new_thread.get()); + return new_thread.release(); + } + + void add_thread(thread* thrd) + { + if(thrd) + { + boost::lock_guard<shared_mutex> guard(m); + threads.push_back(thrd); + } + } + + void remove_thread(thread* thrd) + { + boost::lock_guard<shared_mutex> guard(m); + std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd); + if(it!=threads.end()) + { + threads.erase(it); + } + } + + void join_all() + { + boost::shared_lock<shared_mutex> guard(m); + + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + (*it)->join(); + } + } + + void interrupt_all() + { + boost::shared_lock<shared_mutex> guard(m); + + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + (*it)->interrupt(); + } + } + + size_t size() const + { + boost::shared_lock<shared_mutex> guard(m); + return threads.size(); + } + + private: + std::list<thread*> threads; + mutable shared_mutex m; + }; +} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp new file mode 100644 index 0000000..60c0e65 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP +#define BOOST_THREAD_DETAIL_THREAD_INTERRUPTION_HPP +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// (C) Copyright 2007-9 Anthony Williams + +namespace boost +{ + namespace this_thread + { + class BOOST_THREAD_DECL disable_interruption + { + disable_interruption(const disable_interruption&); + disable_interruption& operator=(const disable_interruption&); + + bool interruption_was_enabled; + friend class restore_interruption; + public: + disable_interruption(); + ~disable_interruption(); + }; + + class BOOST_THREAD_DECL restore_interruption + { + restore_interruption(const restore_interruption&); + restore_interruption& operator=(const restore_interruption&); + public: + explicit restore_interruption(disable_interruption& d); + ~restore_interruption(); + }; + } +} + +#endif diff --git a/3rdParty/Boost/src/boost/thread/exceptions.hpp b/3rdParty/Boost/src/boost/thread/exceptions.hpp index 49e244f..2a05b50 100644 --- a/3rdParty/Boost/src/boost/thread/exceptions.hpp +++ b/3rdParty/Boost/src/boost/thread/exceptions.hpp @@ -1,6 +1,6 @@ // Copyright (C) 2001-2003 // William E. Kempf -// Copyright (C) 2007-8 Anthony Williams +// Copyright (C) 2007-9 Anthony Williams // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,23 +24,36 @@ namespace boost { - class BOOST_THREAD_DECL thread_interrupted + class thread_interrupted {}; -class BOOST_THREAD_DECL thread_exception : public std::exception -{ -protected: - thread_exception(); - thread_exception(int sys_err_code); + class thread_exception: + public std::exception + { + protected: + thread_exception(): + m_sys_err(0) + {} + + thread_exception(int sys_err_code): + m_sys_err(sys_err_code) + {} + -public: - ~thread_exception() throw(); + public: + ~thread_exception() throw() + {} + - int native_error() const; + int native_error() const + { + return m_sys_err; + } + -private: - int m_sys_err; -}; + private: + int m_sys_err; + }; class condition_error: public std::exception @@ -53,62 +66,117 @@ private: }; -class BOOST_THREAD_DECL lock_error : public thread_exception -{ -public: - lock_error(); - lock_error(int sys_err_code); - ~lock_error() throw(); + class lock_error: + public thread_exception + { + public: + lock_error() + {} + + lock_error(int sys_err_code): + thread_exception(sys_err_code) + {} + + ~lock_error() throw() + {} + - virtual const char* what() const throw(); -}; + virtual const char* what() const throw() + { + return "boost::lock_error"; + } + }; -class BOOST_THREAD_DECL thread_resource_error : public thread_exception -{ -public: - thread_resource_error(); - thread_resource_error(int sys_err_code); - ~thread_resource_error() throw(); + class thread_resource_error: + public thread_exception + { + public: + thread_resource_error() + {} + + thread_resource_error(int sys_err_code): + thread_exception(sys_err_code) + {} + + ~thread_resource_error() throw() + {} + - virtual const char* what() const throw(); -}; + virtual const char* what() const throw() + { + return "boost::thread_resource_error"; + } + + }; -class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception -{ -public: - unsupported_thread_option(); - unsupported_thread_option(int sys_err_code); - ~unsupported_thread_option() throw(); + class unsupported_thread_option: + public thread_exception + { + public: + unsupported_thread_option() + {} + + unsupported_thread_option(int sys_err_code): + thread_exception(sys_err_code) + {} + + ~unsupported_thread_option() throw() + {} + - virtual const char* what() const throw(); -}; + virtual const char* what() const throw() + { + return "boost::unsupported_thread_option"; + } + + }; -class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception -{ -public: - invalid_thread_argument(); - invalid_thread_argument(int sys_err_code); - ~invalid_thread_argument() throw(); + class invalid_thread_argument: + public thread_exception + { + public: + invalid_thread_argument() + {} + + invalid_thread_argument(int sys_err_code): + thread_exception(sys_err_code) + {} + + ~invalid_thread_argument() throw() + {} + - virtual const char* what() const throw(); -}; + virtual const char* what() const throw() + { + return "boost::invalid_thread_argument"; + } + + }; -class BOOST_THREAD_DECL thread_permission_error : public thread_exception -{ -public: - thread_permission_error(); - thread_permission_error(int sys_err_code); - ~thread_permission_error() throw(); + class thread_permission_error: + public thread_exception + { + public: + thread_permission_error() + {} + + thread_permission_error(int sys_err_code): + thread_exception(sys_err_code) + {} + + ~thread_permission_error() throw() + {} + - virtual const char* what() const throw(); -}; + virtual const char* what() const throw() + { + return "boost::thread_permission_error"; + } + + }; } // namespace boost #include <boost/config/abi_suffix.hpp> -#endif // BOOST_THREAD_CONFIG_PDM070801_H - -// Change log: -// 3 Jan 03 WEKEMPF Modified for DLL implementation. - +#endif diff --git a/3rdParty/Boost/src/boost/thread/future.hpp b/3rdParty/Boost/src/boost/thread/future.hpp new file mode 100644 index 0000000..3d694eb --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/future.hpp @@ -0,0 +1,1364 @@ +// (C) Copyright 2008-9 Anthony Williams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_THREAD_FUTURE_HPP +#define BOOST_THREAD_FUTURE_HPP +#include <stdexcept> +#include <boost/thread/detail/move.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/exception_ptr.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/type_traits/is_fundamental.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/mpl/if.hpp> +#include <boost/config.hpp> +#include <algorithm> +#include <boost/function.hpp> +#include <boost/bind.hpp> +#include <boost/ref.hpp> +#include <boost/scoped_array.hpp> +#include <boost/utility/enable_if.hpp> +#include <list> +#include <boost/next_prior.hpp> +#include <vector> + +namespace boost +{ + class future_uninitialized: + public std::logic_error + { + public: + future_uninitialized(): + std::logic_error("Future Uninitialized") + {} + }; + class broken_promise: + public std::logic_error + { + public: + broken_promise(): + std::logic_error("Broken promise") + {} + }; + class future_already_retrieved: + public std::logic_error + { + public: + future_already_retrieved(): + std::logic_error("Future already retrieved") + {} + }; + class promise_already_satisfied: + public std::logic_error + { + public: + promise_already_satisfied(): + std::logic_error("Promise already satisfied") + {} + }; + + class task_already_started: + public std::logic_error + { + public: + task_already_started(): + std::logic_error("Task already started") + {} + }; + + class task_moved: + public std::logic_error + { + public: + task_moved(): + std::logic_error("Task moved") + {} + }; + + namespace future_state + { + enum state { uninitialized, waiting, ready, moved }; + } + + namespace detail + { + struct future_object_base + { + boost::exception_ptr exception; + bool done; + boost::mutex mutex; + boost::condition_variable waiters; + typedef std::list<boost::condition_variable_any*> waiter_list; + waiter_list external_waiters; + boost::function<void()> callback; + + future_object_base(): + done(false) + {} + virtual ~future_object_base() + {} + + waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv) + { + boost::unique_lock<boost::mutex> lock(mutex); + do_callback(lock); + return external_waiters.insert(external_waiters.end(),&cv); + } + + void remove_external_waiter(waiter_list::iterator it) + { + boost::lock_guard<boost::mutex> lock(mutex); + external_waiters.erase(it); + } + + void mark_finished_internal() + { + done=true; + waiters.notify_all(); + for(waiter_list::const_iterator it=external_waiters.begin(), + end=external_waiters.end();it!=end;++it) + { + (*it)->notify_all(); + } + } + + struct relocker + { + boost::unique_lock<boost::mutex>& lock; + + relocker(boost::unique_lock<boost::mutex>& lock_): + lock(lock_) + { + lock.unlock(); + } + ~relocker() + { + lock.lock(); + } + }; + + void do_callback(boost::unique_lock<boost::mutex>& lock) + { + if(callback && !done) + { + boost::function<void()> local_callback=callback; + relocker relock(lock); + local_callback(); + } + } + + + void wait(bool rethrow=true) + { + boost::unique_lock<boost::mutex> lock(mutex); + do_callback(lock); + while(!done) + { + waiters.wait(lock); + } + if(rethrow && exception) + { + boost::rethrow_exception(exception); + } + } + + bool timed_wait_until(boost::system_time const& target_time) + { + boost::unique_lock<boost::mutex> lock(mutex); + do_callback(lock); + while(!done) + { + bool const success=waiters.timed_wait(lock,target_time); + if(!success && !done) + { + return false; + } + } + return true; + } + + void mark_exceptional_finish_internal(boost::exception_ptr const& e) + { + exception=e; + mark_finished_internal(); + } + void mark_exceptional_finish() + { + boost::lock_guard<boost::mutex> lock(mutex); + mark_exceptional_finish_internal(boost::current_exception()); + } + + bool has_value() + { + boost::lock_guard<boost::mutex> lock(mutex); + return done && !exception; + } + bool has_exception() + { + boost::lock_guard<boost::mutex> lock(mutex); + return done && exception; + } + + template<typename F,typename U> + void set_wait_callback(F f,U* u) + { + callback=boost::bind(f,boost::ref(*u)); + } + + private: + future_object_base(future_object_base const&); + future_object_base& operator=(future_object_base const&); + }; + + template<typename T> + struct future_traits + { + typedef boost::scoped_ptr<T> storage_type; +#ifdef BOOST_HAS_RVALUE_REFS + typedef T const& source_reference_type; + struct dummy; + typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type; + typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type; +#else + typedef T& source_reference_type; + typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type; + typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type; +#endif + + static void init(storage_type& storage,source_reference_type t) + { + storage.reset(new T(t)); + } + + static void init(storage_type& storage,rvalue_source_type t) + { + storage.reset(new T(static_cast<rvalue_source_type>(t))); + } + + static void cleanup(storage_type& storage) + { + storage.reset(); + } + }; + + template<typename T> + struct future_traits<T&> + { + typedef T* storage_type; + typedef T& source_reference_type; + struct rvalue_source_type + {}; + typedef T& move_dest_type; + + static void init(storage_type& storage,T& t) + { + storage=&t; + } + + static void cleanup(storage_type& storage) + { + storage=0; + } + }; + + template<> + struct future_traits<void> + { + typedef bool storage_type; + typedef void move_dest_type; + + static void init(storage_type& storage) + { + storage=true; + } + + static void cleanup(storage_type& storage) + { + storage=false; + } + + }; + + template<typename T> + struct future_object: + detail::future_object_base + { + typedef typename future_traits<T>::storage_type storage_type; + typedef typename future_traits<T>::source_reference_type source_reference_type; + typedef typename future_traits<T>::rvalue_source_type rvalue_source_type; + typedef typename future_traits<T>::move_dest_type move_dest_type; + + storage_type result; + + future_object(): + result(0) + {} + + void mark_finished_with_result_internal(source_reference_type result_) + { + future_traits<T>::init(result,result_); + mark_finished_internal(); + } + void mark_finished_with_result_internal(rvalue_source_type result_) + { + future_traits<T>::init(result,static_cast<rvalue_source_type>(result_)); + mark_finished_internal(); + } + + void mark_finished_with_result(source_reference_type result_) + { + boost::lock_guard<boost::mutex> lock(mutex); + mark_finished_with_result_internal(result_); + } + void mark_finished_with_result(rvalue_source_type result_) + { + boost::lock_guard<boost::mutex> lock(mutex); + mark_finished_with_result_internal(result_); + } + + move_dest_type get() + { + wait(); + return *result; + } + + future_state::state get_state() + { + boost::lock_guard<boost::mutex> guard(mutex); + if(!done) + { + return future_state::waiting; + } + else + { + return future_state::ready; + } + } + + private: + future_object(future_object const&); + future_object& operator=(future_object const&); + }; + + template<> + struct future_object<void>: + detail::future_object_base + { + future_object() + {} + + void mark_finished_with_result_internal() + { + mark_finished_internal(); + } + + void mark_finished_with_result() + { + boost::lock_guard<boost::mutex> lock(mutex); + mark_finished_with_result_internal(); + } + + void get() + { + wait(); + } + + future_state::state get_state() + { + boost::lock_guard<boost::mutex> guard(mutex); + if(!done) + { + return future_state::waiting; + } + else + { + return future_state::ready; + } + } + + private: + future_object(future_object const&); + future_object& operator=(future_object const&); + }; + + class future_waiter + { + struct registered_waiter + { + boost::shared_ptr<detail::future_object_base> future; + detail::future_object_base::waiter_list::iterator wait_iterator; + unsigned index; + + registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_, + detail::future_object_base::waiter_list::iterator wait_iterator_, + unsigned index_): + future(future_),wait_iterator(wait_iterator_),index(index_) + {} + + }; + + struct all_futures_lock + { + unsigned count; + boost::scoped_array<boost::unique_lock<boost::mutex> > locks; + + all_futures_lock(std::vector<registered_waiter>& futures): + count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count]) + { + for(unsigned i=0;i<count;++i) + { + locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex); + } + } + + void lock() + { + boost::lock(locks.get(),locks.get()+count); + } + + void unlock() + { + for(unsigned i=0;i<count;++i) + { + locks[i].unlock(); + } + } + }; + + boost::condition_variable_any cv; + std::vector<registered_waiter> futures; + unsigned future_count; + + public: + future_waiter(): + future_count(0) + {} + + template<typename F> + void add(F& f) + { + if(f.future) + { + futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count)); + } + ++future_count; + } + + unsigned wait() + { + all_futures_lock lk(futures); + for(;;) + { + for(unsigned i=0;i<futures.size();++i) + { + if(futures[i].future->done) + { + return futures[i].index; + } + } + cv.wait(lk); + } + } + + ~future_waiter() + { + for(unsigned i=0;i<futures.size();++i) + { + futures[i].future->remove_external_waiter(futures[i].wait_iterator); + } + } + + }; + + } + + template <typename R> + class unique_future; + + template <typename R> + class shared_future; + + template<typename T> + struct is_future_type + { + BOOST_STATIC_CONSTANT(bool, value=false); + }; + + template<typename T> + struct is_future_type<unique_future<T> > + { + BOOST_STATIC_CONSTANT(bool, value=true); + }; + + template<typename T> + struct is_future_type<shared_future<T> > + { + BOOST_STATIC_CONSTANT(bool, value=true); + }; + + template<typename Iterator> + typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end) + { + for(Iterator current=begin;current!=end;++current) + { + current->wait(); + } + } + + template<typename F1,typename F2> + typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2) + { + f1.wait(); + f2.wait(); + } + + template<typename F1,typename F2,typename F3> + void wait_for_all(F1& f1,F2& f2,F3& f3) + { + f1.wait(); + f2.wait(); + f3.wait(); + } + + template<typename F1,typename F2,typename F3,typename F4> + void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4) + { + f1.wait(); + f2.wait(); + f3.wait(); + f4.wait(); + } + + template<typename F1,typename F2,typename F3,typename F4,typename F5> + void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) + { + f1.wait(); + f2.wait(); + f3.wait(); + f4.wait(); + f5.wait(); + } + + template<typename Iterator> + typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end) + { + detail::future_waiter waiter; + for(Iterator current=begin;current!=end;++current) + { + waiter.add(*current); + } + return boost::next(begin,waiter.wait()); + } + + template<typename F1,typename F2> + typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2) + { + detail::future_waiter waiter; + waiter.add(f1); + waiter.add(f2); + return waiter.wait(); + } + + template<typename F1,typename F2,typename F3> + unsigned wait_for_any(F1& f1,F2& f2,F3& f3) + { + detail::future_waiter waiter; + waiter.add(f1); + waiter.add(f2); + waiter.add(f3); + return waiter.wait(); + } + + template<typename F1,typename F2,typename F3,typename F4> + unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4) + { + detail::future_waiter waiter; + waiter.add(f1); + waiter.add(f2); + waiter.add(f3); + waiter.add(f4); + return waiter.wait(); + } + + template<typename F1,typename F2,typename F3,typename F4,typename F5> + unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5) + { + detail::future_waiter waiter; + waiter.add(f1); + waiter.add(f2); + waiter.add(f3); + waiter.add(f4); + waiter.add(f5); + return waiter.wait(); + } + + template <typename R> + class promise; + + template <typename R> + class packaged_task; + + template <typename R> + class unique_future + { + unique_future(unique_future & rhs);// = delete; + unique_future& operator=(unique_future& rhs);// = delete; + + typedef boost::shared_ptr<detail::future_object<R> > future_ptr; + + future_ptr future; + + friend class shared_future<R>; + friend class promise<R>; + friend class packaged_task<R>; + friend class detail::future_waiter; + + typedef typename detail::future_traits<R>::move_dest_type move_dest_type; + + unique_future(future_ptr future_): + future(future_) + {} + + public: + typedef future_state::state state; + + unique_future() + {} + + ~unique_future() + {} + +#ifdef BOOST_HAS_RVALUE_REFS + unique_future(unique_future && other) + { + future.swap(other.future); + } + unique_future& operator=(unique_future && other) + { + future=other.future; + other.future.reset(); + return *this; + } +#else + unique_future(boost::detail::thread_move_t<unique_future> other): + future(other->future) + { + other->future.reset(); + } + + unique_future& operator=(boost::detail::thread_move_t<unique_future> other) + { + future=other->future; + other->future.reset(); + return *this; + } + + operator boost::detail::thread_move_t<unique_future>() + { + return boost::detail::thread_move_t<unique_future>(*this); + } +#endif + + void swap(unique_future& other) + { + future.swap(other.future); + } + + // retrieving the value + move_dest_type get() + { + if(!future) + { + throw future_uninitialized(); + } + + return future->get(); + } + + // functions to check state, and wait for ready + state get_state() const + { + if(!future) + { + return future_state::uninitialized; + } + return future->get_state(); + } + + + bool is_ready() const + { + return get_state()==future_state::ready; + } + + bool has_exception() const + { + return future && future->has_exception(); + } + + bool has_value() const + { + return future && future->has_value(); + } + + void wait() const + { + if(!future) + { + throw future_uninitialized(); + } + future->wait(false); + } + + template<typename Duration> + bool timed_wait(Duration const& rel_time) const + { + return timed_wait_until(boost::get_system_time()+rel_time); + } + + bool timed_wait_until(boost::system_time const& abs_time) const + { + if(!future) + { + throw future_uninitialized(); + } + return future->timed_wait_until(abs_time); + } + + }; + + template <typename R> + class shared_future + { + typedef boost::shared_ptr<detail::future_object<R> > future_ptr; + + future_ptr future; + +// shared_future(const unique_future<R>& other); +// shared_future& operator=(const unique_future<R>& other); + + friend class detail::future_waiter; + friend class promise<R>; + friend class packaged_task<R>; + + shared_future(future_ptr future_): + future(future_) + {} + + public: + shared_future(shared_future const& other): + future(other.future) + {} + + typedef future_state::state state; + + shared_future() + {} + + ~shared_future() + {} + + shared_future& operator=(shared_future const& other) + { + future=other.future; + return *this; + } +#ifdef BOOST_HAS_RVALUE_REFS + shared_future(shared_future && other) + { + future.swap(other.future); + } + shared_future(unique_future<R> && other) + { + future.swap(other.future); + } + shared_future& operator=(shared_future && other) + { + future.swap(other.future); + other.future.reset(); + return *this; + } + shared_future& operator=(unique_future<R> && other) + { + future.swap(other.future); + other.future.reset(); + return *this; + } +#else + shared_future(boost::detail::thread_move_t<shared_future> other): + future(other->future) + { + other->future.reset(); + } +// shared_future(const unique_future<R> &) = delete; + shared_future(boost::detail::thread_move_t<unique_future<R> > other): + future(other->future) + { + other->future.reset(); + } + shared_future& operator=(boost::detail::thread_move_t<shared_future> other) + { + future.swap(other->future); + other->future.reset(); + return *this; + } + shared_future& operator=(boost::detail::thread_move_t<unique_future<R> > other) + { + future.swap(other->future); + other->future.reset(); + return *this; + } + + operator boost::detail::thread_move_t<shared_future>() + { + return boost::detail::thread_move_t<shared_future>(*this); + } + +#endif + + void swap(shared_future& other) + { + future.swap(other.future); + } + + // retrieving the value + R get() + { + if(!future) + { + throw future_uninitialized(); + } + + return future->get(); + } + + // functions to check state, and wait for ready + state get_state() const + { + if(!future) + { + return future_state::uninitialized; + } + return future->get_state(); + } + + + bool is_ready() const + { + return get_state()==future_state::ready; + } + + bool has_exception() const + { + return future && future->has_exception(); + } + + bool has_value() const + { + return future && future->has_value(); + } + + void wait() const + { + if(!future) + { + throw future_uninitialized(); + } + future->wait(false); + } + + template<typename Duration> + bool timed_wait(Duration const& rel_time) const + { + return timed_wait_until(boost::get_system_time()+rel_time); + } + + bool timed_wait_until(boost::system_time const& abs_time) const + { + if(!future) + { + throw future_uninitialized(); + } + return future->timed_wait_until(abs_time); + } + + }; + + template <typename R> + class promise + { + typedef boost::shared_ptr<detail::future_object<R> > future_ptr; + + future_ptr future; + bool future_obtained; + + promise(promise & rhs);// = delete; + promise & operator=(promise & rhs);// = delete; + + void lazy_init() + { + if(!future) + { + future_obtained=false; + future.reset(new detail::future_object<R>); + } + } + + public: +// template <class Allocator> explicit promise(Allocator a); + + promise(): + future(),future_obtained(false) + {} + + ~promise() + { + if(future) + { + boost::lock_guard<boost::mutex> lock(future->mutex); + + if(!future->done) + { + future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); + } + } + } + + // Assignment +#ifdef BOOST_HAS_RVALUE_REFS + promise(promise && rhs): + future_obtained(rhs.future_obtained) + { + future.swap(rhs.future); + } + promise & operator=(promise&& rhs) + { + future.swap(rhs.future); + future_obtained=rhs.future_obtained; + rhs.future.reset(); + return *this; + } +#else + promise(boost::detail::thread_move_t<promise> rhs): + future(rhs->future),future_obtained(rhs->future_obtained) + { + rhs->future.reset(); + } + promise & operator=(boost::detail::thread_move_t<promise> rhs) + { + future=rhs->future; + future_obtained=rhs->future_obtained; + rhs->future.reset(); + return *this; + } + + operator boost::detail::thread_move_t<promise>() + { + return boost::detail::thread_move_t<promise>(*this); + } +#endif + + void swap(promise& other) + { + future.swap(other.future); + std::swap(future_obtained,other.future_obtained); + } + + // Result retrieval + unique_future<R> get_future() + { + lazy_init(); + if(future_obtained) + { + throw future_already_retrieved(); + } + future_obtained=true; + return unique_future<R>(future); + } + + void set_value(typename detail::future_traits<R>::source_reference_type r) + { + lazy_init(); + boost::lock_guard<boost::mutex> lock(future->mutex); + if(future->done) + { + throw promise_already_satisfied(); + } + future->mark_finished_with_result_internal(r); + } + +// void set_value(R && r); + void set_value(typename detail::future_traits<R>::rvalue_source_type r) + { + lazy_init(); + boost::lock_guard<boost::mutex> lock(future->mutex); + if(future->done) + { + throw promise_already_satisfied(); + } + future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r)); + } + + void set_exception(boost::exception_ptr p) + { + lazy_init(); + boost::lock_guard<boost::mutex> lock(future->mutex); + if(future->done) + { + throw promise_already_satisfied(); + } + future->mark_exceptional_finish_internal(p); + } + + template<typename F> + void set_wait_callback(F f) + { + lazy_init(); + future->set_wait_callback(f,this); + } + + }; + + template <> + class promise<void> + { + typedef boost::shared_ptr<detail::future_object<void> > future_ptr; + + future_ptr future; + bool future_obtained; + + promise(promise & rhs);// = delete; + promise & operator=(promise & rhs);// = delete; + + void lazy_init() + { + if(!future) + { + future_obtained=false; + future.reset(new detail::future_object<void>); + } + } + public: +// template <class Allocator> explicit promise(Allocator a); + + promise(): + future(),future_obtained(false) + {} + + ~promise() + { + if(future) + { + boost::lock_guard<boost::mutex> lock(future->mutex); + + if(!future->done) + { + future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); + } + } + } + + // Assignment +#ifdef BOOST_HAS_RVALUE_REFS + promise(promise && rhs): + future_obtained(rhs.future_obtained) + { + future.swap(rhs.future); + } + promise & operator=(promise&& rhs) + { + future.swap(rhs.future); + future_obtained=rhs.future_obtained; + rhs.future.reset(); + return *this; + } +#else + promise(boost::detail::thread_move_t<promise> rhs): + future(rhs->future),future_obtained(rhs->future_obtained) + { + rhs->future.reset(); + } + promise & operator=(boost::detail::thread_move_t<promise> rhs) + { + future=rhs->future; + future_obtained=rhs->future_obtained; + rhs->future.reset(); + return *this; + } + + operator boost::detail::thread_move_t<promise>() + { + return boost::detail::thread_move_t<promise>(*this); + } +#endif + + void swap(promise& other) + { + future.swap(other.future); + std::swap(future_obtained,other.future_obtained); + } + + // Result retrieval + unique_future<void> get_future() + { + lazy_init(); + + if(future_obtained) + { + throw future_already_retrieved(); + } + future_obtained=true; + return unique_future<void>(future); + } + + void set_value() + { + lazy_init(); + boost::lock_guard<boost::mutex> lock(future->mutex); + if(future->done) + { + throw promise_already_satisfied(); + } + future->mark_finished_with_result_internal(); + } + + void set_exception(boost::exception_ptr p) + { + lazy_init(); + boost::lock_guard<boost::mutex> lock(future->mutex); + if(future->done) + { + throw promise_already_satisfied(); + } + future->mark_exceptional_finish_internal(p); + } + + template<typename F> + void set_wait_callback(F f) + { + lazy_init(); + future->set_wait_callback(f,this); + } + + }; + + namespace detail + { + template<typename R> + struct task_base: + detail::future_object<R> + { + bool started; + + task_base(): + started(false) + {} + + void run() + { + { + boost::lock_guard<boost::mutex> lk(this->mutex); + if(started) + { + throw task_already_started(); + } + started=true; + } + do_run(); + } + + void owner_destroyed() + { + boost::lock_guard<boost::mutex> lk(this->mutex); + if(!started) + { + started=true; + this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise())); + } + } + + + virtual void do_run()=0; + }; + + + template<typename R,typename F> + struct task_object: + task_base<R> + { + F f; + task_object(F const& f_): + f(f_) + {} + task_object(boost::detail::thread_move_t<F> f_): + f(f_) + {} + + void do_run() + { + try + { + this->mark_finished_with_result(f()); + } + catch(...) + { + this->mark_exceptional_finish(); + } + } + }; + + template<typename F> + struct task_object<void,F>: + task_base<void> + { + F f; + task_object(F const& f_): + f(f_) + {} + task_object(boost::detail::thread_move_t<F> f_): + f(f_) + {} + + void do_run() + { + try + { + f(); + this->mark_finished_with_result(); + } + catch(...) + { + this->mark_exceptional_finish(); + } + } + }; + + } + + + template<typename R> + class packaged_task + { + boost::shared_ptr<detail::task_base<R> > task; + bool future_obtained; + + packaged_task(packaged_task&);// = delete; + packaged_task& operator=(packaged_task&);// = delete; + + public: + packaged_task(): + future_obtained(false) + {} + + // construction and destruction + template <class F> + explicit packaged_task(F const& f): + task(new detail::task_object<R,F>(f)),future_obtained(false) + {} + explicit packaged_task(R(*f)()): + task(new detail::task_object<R,R(*)()>(f)),future_obtained(false) + {} + + template <class F> + explicit packaged_task(boost::detail::thread_move_t<F> f): + task(new detail::task_object<R,F>(f)),future_obtained(false) + {} + +// template <class F, class Allocator> +// explicit packaged_task(F const& f, Allocator a); +// template <class F, class Allocator> +// explicit packaged_task(F&& f, Allocator a); + + + ~packaged_task() + { + if(task) + { + task->owner_destroyed(); + } + } + + // assignment +#ifdef BOOST_HAS_RVALUE_REFS + packaged_task(packaged_task&& other): + future_obtained(other.future_obtained) + { + task.swap(other.task); + other.future_obtained=false; + } + packaged_task& operator=(packaged_task&& other) + { + packaged_task temp(static_cast<packaged_task&&>(other)); + swap(temp); + return *this; + } +#else + packaged_task(boost::detail::thread_move_t<packaged_task> other): + future_obtained(other->future_obtained) + { + task.swap(other->task); + other->future_obtained=false; + } + packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other) + { + packaged_task temp(other); + swap(temp); + return *this; + } + operator boost::detail::thread_move_t<packaged_task>() + { + return boost::detail::thread_move_t<packaged_task>(*this); + } +#endif + + void swap(packaged_task& other) + { + task.swap(other.task); + std::swap(future_obtained,other.future_obtained); + } + + // result retrieval + unique_future<R> get_future() + { + if(!task) + { + throw task_moved(); + } + else if(!future_obtained) + { + future_obtained=true; + return unique_future<R>(task); + } + else + { + throw future_already_retrieved(); + } + } + + + // execution + void operator()() + { + if(!task) + { + throw task_moved(); + } + task->run(); + } + + template<typename F> + void set_wait_callback(F f) + { + task->set_wait_callback(f,this); + } + + }; + +} + + +#endif diff --git a/3rdParty/Boost/src/boost/thread/locks.hpp b/3rdParty/Boost/src/boost/thread/locks.hpp index abbfd75..82394a5 100644 --- a/3rdParty/Boost/src/boost/thread/locks.hpp +++ b/3rdParty/Boost/src/boost/thread/locks.hpp @@ -214,6 +214,9 @@ namespace boost unique_lock& operator=(unique_lock&); unique_lock& operator=(upgrade_lock<Mutex>& other); public: +#ifdef __SUNPRO_CC + unique_lock(const volatile unique_lock&); +#endif unique_lock(): m(0),is_locked(false) {} @@ -260,16 +263,16 @@ namespace boost } - unique_lock& operator=(unique_lock<Mutex>&& other) + unique_lock& operator=(unique_lock&& other) { - unique_lock temp(other); + unique_lock temp(other.move()); swap(temp); return *this; } unique_lock& operator=(upgrade_lock<Mutex>&& other) { - unique_lock temp(other); + unique_lock temp(other.move()); swap(temp); return *this; } @@ -297,12 +300,20 @@ namespace boost return detail::thread_move_t<unique_lock<Mutex> >(*this); } +#ifdef __SUNPRO_CC + unique_lock& operator=(unique_lock<Mutex> other) + { + swap(other); + return *this; + } +#else unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) { unique_lock temp(other); swap(temp); return *this; } +#endif unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) { @@ -772,7 +783,7 @@ namespace boost other.is_locked=false; if(is_locked) { - m.unlock_upgrade_and_lock(); + m->unlock_upgrade_and_lock(); } } #else @@ -864,6 +875,28 @@ namespace boost try_lock_wrapper(Mutex& m_,try_to_lock_t): base(m_,try_to_lock) {} +#ifdef BOOST_HAS_RVALUE_REFS + try_lock_wrapper(try_lock_wrapper&& other): + base(other.move()) + {} + + try_lock_wrapper&& move() + { + return static_cast<try_lock_wrapper&&>(*this); + } + + try_lock_wrapper& operator=(try_lock_wrapper<Mutex>&& other) + { + try_lock_wrapper temp(other.move()); + swap(temp); + return *this; + } + + void swap(try_lock_wrapper&& other) + { + base::swap(other); + } +#else try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other): base(detail::thread_move_t<base>(*other)) {} @@ -885,12 +918,6 @@ namespace boost return *this; } -#ifdef BOOST_HAS_RVALUE_REFS - void swap(try_lock_wrapper&& other) - { - base::swap(other); - } -#else void swap(try_lock_wrapper& other) { base::swap(other); @@ -900,7 +927,6 @@ namespace boost base::swap(*other); } #endif - void lock() { base::lock(); diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index 3ce4e23..30440eb 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -10,8 +10,8 @@ #include <boost/assert.hpp> #include <boost/static_assert.hpp> #include <boost/thread/mutex.hpp> -#include <boost/thread/thread.hpp> #include <boost/thread/condition_variable.hpp> +#include <boost/thread/detail/thread_interruption.hpp> #include <boost/config/abi_prefix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 244035b..730c77c 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -13,6 +13,7 @@ #include <boost/optional.hpp> #include <pthread.h> #include "condition_variable_fwd.hpp" +#include <map> #include <boost/config/abi_prefix.hpp> @@ -22,8 +23,18 @@ namespace boost namespace detail { + struct tss_cleanup_function; struct thread_exit_callback_node; - struct tss_data_node; + struct tss_data_node + { + boost::shared_ptr<boost::detail::tss_cleanup_function> func; + void* value; + + tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, + void* value_): + func(func_),value(value_) + {} + }; struct thread_data_base; typedef boost::shared_ptr<thread_data_base> thread_data_ptr; @@ -41,14 +52,14 @@ namespace boost bool join_started; bool joined; boost::detail::thread_exit_callback_node* thread_exit_callbacks; - boost::detail::tss_data_node* tss_data; + std::map<void const*,boost::detail::tss_data_node> tss_data; bool interrupt_enabled; bool interrupt_requested; pthread_cond_t* current_cond; thread_data_base(): done(false),join_started(false),joined(false), - thread_exit_callbacks(0),tss_data(0), + thread_exit_callbacks(0), interrupt_enabled(true), interrupt_requested(false), current_cond(0) diff --git a/3rdParty/Boost/src/boost/thread/thread.hpp b/3rdParty/Boost/src/boost/thread/thread.hpp index 6146132..fdfdadc 100644 --- a/3rdParty/Boost/src/boost/thread/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/thread.hpp @@ -20,6 +20,8 @@ #endif #include <boost/thread/detail/thread.hpp> +#include <boost/thread/detail/thread_interruption.hpp> +#include <boost/thread/detail/thread_group.hpp> #endif diff --git a/3rdParty/Boost/src/boost/thread/tss.hpp b/3rdParty/Boost/src/boost/thread/tss.hpp index 76380aa..e38e3e9 100644 --- a/3rdParty/Boost/src/boost/thread/tss.hpp +++ b/3rdParty/Boost/src/boost/thread/tss.hpp @@ -74,7 +74,7 @@ namespace boost } ~thread_specific_ptr() { - reset(); + detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true); } T* get() const |