Index: future.hpp =================================================================== --- future.hpp (revision 76073) +++ future.hpp (working copy) @@ -6,6 +6,7 @@ #ifndef BOOST_THREAD_FUTURE_HPP #define BOOST_THREAD_FUTURE_HPP + #include #include #include @@ -93,6 +94,7 @@ { boost::exception_ptr exception; bool done; + bool thread_was_interrupted; boost::mutex mutex; boost::condition_variable waiters; typedef std::list waiter_list; @@ -100,7 +102,8 @@ boost::function callback; future_object_base(): - done(false) + done(false), + thread_was_interrupted(false) {} virtual ~future_object_base() {} @@ -165,6 +168,10 @@ { waiters.wait(lock); } + if(rethrow && thread_was_interrupted) + { + throw boost::thread_interrupted(); + } if(rethrow && exception) { boost::rethrow_exception(exception); @@ -196,16 +203,21 @@ boost::lock_guard lock(mutex); mark_exceptional_finish_internal(boost::current_exception()); } - + void mark_interrupted_finish() + { + boost::lock_guard lock(mutex); + thread_was_interrupted=true; + mark_finished_internal(); + } bool has_value() { boost::lock_guard lock(mutex); - return done && !exception; + return done && !(exception || thread_was_interrupted); } bool has_exception() { boost::lock_guard lock(mutex); - return done && exception; + return done && (exception || thread_was_interrupted); } template @@ -233,6 +245,7 @@ typedef typename boost::mpl::if_ >,boost::detail::thread_move_t,T const&>::type rvalue_source_type; typedef typename boost::mpl::if_ >,boost::detail::thread_move_t,T>::type move_dest_type; #endif + typedef const T& shared_future_get_result_type; static void init(storage_type& storage,source_reference_type t) { @@ -258,6 +271,7 @@ struct rvalue_source_type {}; typedef T& move_dest_type; + typedef T& shared_future_get_result_type; static void init(storage_type& storage,T& t) { @@ -275,6 +289,7 @@ { typedef bool storage_type; typedef void move_dest_type; + typedef void shared_future_get_result_type; static void init(storage_type& storage) { @@ -296,6 +311,7 @@ typedef typename future_traits::source_reference_type source_reference_type; typedef typename future_traits::rvalue_source_type rvalue_source_type; typedef typename future_traits::move_dest_type move_dest_type; + typedef typename future_traits::shared_future_get_result_type shared_future_get_result_type; storage_type result; @@ -331,6 +347,12 @@ return static_cast(*result); } + shared_future_get_result_type get_sh() + { + wait(); + return static_cast(*result); + } + future_state::state get_state() { boost::lock_guard guard(mutex); @@ -353,7 +375,7 @@ struct future_object: detail::future_object_base { - typedef void move_dest_type; + typedef void shared_future_get_result_type; future_object() {} @@ -373,7 +395,10 @@ { wait(); } - + void get_sh() + { + wait(); + } future_state::state get_state() { boost::lock_guard guard(mutex); @@ -413,19 +438,13 @@ struct all_futures_lock { -#ifdef _MANAGED - typedef std::ptrdiff_t count_type_portable; -#else - typedef count_type count_type_portable; -#endif - count_type_portable count; - + count_type count; boost::scoped_array > locks; all_futures_lock(std::vector& futures): count(futures.size()),locks(new boost::unique_lock[count]) { - for(count_type_portable i=0;i(futures[i].future->mutex).move(); @@ -442,7 +461,7 @@ void unlock() { - for(count_type_portable i=0;i::move_dest_type get() - R get() + typename detail::future_object::shared_future_get_result_type get() + //R get() { if(!future) { boost::throw_exception(future_uninitialized()); } - return future->get(); + return future->get_sh(); } // functions to check state, and wait for ready @@ -1235,13 +1254,16 @@ f(f_) {} #endif - void do_run() { try { this->mark_finished_with_result(f()); } + catch(thread_interrupted& it) + { + this->mark_interrupted_finish(); + } catch(...) { this->mark_exceptional_finish(); @@ -1266,7 +1288,6 @@ f(f_) {} #endif - void do_run() { try @@ -1274,6 +1295,10 @@ f(); this->mark_finished_with_result(); } + catch(thread_interrupted& it) + { + this->mark_interrupted_finish(); + } catch(...) { this->mark_exceptional_finish(); @@ -1318,7 +1343,6 @@ task(new detail::task_object(f)),future_obtained(false) {} #endif - // template // explicit packaged_task(F const& f, Allocator a); // template @@ -1335,6 +1359,7 @@ // assignment #ifndef BOOST_NO_RVALUE_REFERENCES + packaged_task(packaged_task&& other): future_obtained(other.future_obtained) { @@ -1366,7 +1391,7 @@ } #endif - void swap(packaged_task& other) + void swap(packaged_task& other) { task.swap(other.task); std::swap(future_obtained,other.future_obtained);