From 131c92a7d80ac146193b2c2cd138ffb2afc16523 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Mon, 4 May 2015 00:19:12 +0200 Subject: [PATCH] propagate unwrap fixes. --- example/executor.cpp | 6 +-- include/boost/thread/future.hpp | 96 ++++++++++++++++++++++++--------- test/Jamfile.v2 | 17 +++--- test/test_10964.cpp | 29 ---------- 4 files changed, 81 insertions(+), 67 deletions(-) diff --git a/example/executor.cpp b/example/executor.cpp index e4610a1c..f0380e9f 100644 --- a/example/executor.cpp +++ b/example/executor.cpp @@ -89,7 +89,7 @@ int test_executor_adaptor() std::cout << BOOST_CONTEXTOF << std::endl; submit_some( ea); std::cout << BOOST_CONTEXTOF << std::endl; -#if 0 +#if 1 // fixme // ERROR= tr1::bad_weak_ptr { @@ -143,7 +143,7 @@ int test_executor_adaptor() submit_some(ea1); } std::cout << BOOST_CONTEXTOF << std::endl; -#if 0 +#if 1 // fixme // ERROR= tr1::bad_weak_ptr { @@ -156,7 +156,7 @@ int test_executor_adaptor() { boost::async(&f1); } -#if 0 +#if 1 // fixme // ERROR= tr1::bad_weak_ptr diff --git a/include/boost/thread/future.hpp b/include/boost/thread/future.hpp index 20be6121..4f4c6282 100644 --- a/include/boost/thread/future.hpp +++ b/include/boost/thread/future.hpp @@ -5187,31 +5187,75 @@ namespace detail struct future_unwrap_shared_state: shared_state { F wrapped; + typename F::value_type unwrapped; public: explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f) - : wrapped(boost::move(f)) {} - - typename F::value_type parent_value(boost::unique_lock& ) { - typename F::value_type r = wrapped.get(); - r.set_exceptional_if_invalid(); - return boost::move(r); + : wrapped(boost::move(f)) { } - virtual void wait(boost::unique_lock& lk, bool ) { // todo see if rethrow must be used - parent_value(lk).wait(); - } - virtual Rp get(boost::unique_lock& lk) { - return parent_value(lk).get(); - } -#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION - typedef shared_ptr continuation_ptr_type; - - virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock& lock) + void launch_continuation(boost::unique_lock& lk, shared_ptr that) { - boost::unique_lock lk(wrapped.parent.future_->mutex); - wrapped.parent.future_->set_continuation_ptr(continuation, lk); + if (! unwrapped.valid() ) + { + if (wrapped.has_exception()) { + this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk); + } else { + unwrapped = wrapped.get(); + if (unwrapped.valid()) + { + lk.unlock(); + boost::unique_lock lk2(unwrapped.future_->mutex); + unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2); + } else { + this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk); + } + } + } else { + if (unwrapped.has_exception()) { + this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk); + } else { + this->mark_finished_with_result_internal(unwrapped.get(), lk); + } + } + } + }; + + template + struct future_unwrap_shared_state: shared_state + { + F wrapped; + typename F::value_type unwrapped; + public: + explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f) + : wrapped(boost::move(f)) { + } + + void launch_continuation(boost::unique_lock& lk, shared_ptr that) + { + if (! unwrapped.valid() ) + { + if (wrapped.has_exception()) { + this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk); + } else { + unwrapped = wrapped.get(); + if (unwrapped.valid()) + { + lk.unlock(); + boost::unique_lock lk2(unwrapped.future_->mutex); + unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2); + } else { + this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk); + } + } + } else { + if (unwrapped.has_exception()) { + this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk); + } else { + unwrapped.wait(); + this->mark_finished_with_result_internal(lk); + } + } } -#endif }; template @@ -5219,13 +5263,13 @@ namespace detail make_future_unwrap_shared_state(boost::unique_lock &lock, BOOST_THREAD_RV_REF(F) f) { shared_ptr > h(new future_unwrap_shared_state(boost::move(f))); -//#ifdef BOOST_THREAD_FUTURE_BLOCKING -// lock.lock(); -// h->parent.future_->set_continuation_ptr(h, lock); -// lock.unlock(); -//#else -// h->parent.future_->set_continuation_ptr(h, lock); -//#endif +#ifdef BOOST_THREAD_FUTURE_BLOCKING + lock.lock(); + h->wrapped.future_->set_continuation_ptr(h, lock); + lock.unlock(); +#else + h->wrapped.future_->set_continuation_ptr(h, lock); +#endif return BOOST_THREAD_FUTURE(h); } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9b329e80..d4417ac5 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -296,7 +296,7 @@ rule thread-compile ( sources : reqs * : name ) #[ thread-run test_9711.cpp ] This is an invalid use of ::then deferred. [ thread-run test_9856.cpp ] [ thread-compile test_10963.cpp : : test_10963_c ] - #[ thread-run test_10964.cpp ] + [ thread-run test_10964.cpp ] [ thread-test test_11053.cpp ] ; @@ -957,15 +957,14 @@ rule thread-compile ( sources : reqs * : name ) explicit ts_ ; test-suite ts_ : - #[ thread-compile test_10963.cpp : : test_10963_c ] - #[ thread-run test_10964.cpp ] - [ thread-run2 ../example/executor.cpp : ex_executor2 ] + #[ thread-run test_11256.cpp ] + #[ thread-run2 ../example/executor.cpp : ex_executor2 ] #[ thread-run2 ../example/generic_executor_ref.cpp : ex_generic_executor_ref2 ] - [ thread-run2-noit ./sync/futures/async/async_executor_pass.cpp : async__async_executor_p2 ] - [ thread-run2 ../example/fib_task_region.cpp : ex_fib_task_region2 ] - [ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p2 ] - [ thread-run2 ../example/parallel_quick_sort.cpp : ex_parallel_quick_sort2 ] - [ thread-run2 ../example/parallel_accumulate.cpp : ex_parallel_accumulate2 ] + #[ thread-run2-noit ./sync/futures/async/async_executor_pass.cpp : async__async_executor_p2 ] + #[ thread-run2 ../example/fib_task_region.cpp : ex_fib_task_region2 ] + #[ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p2 ] + #[ thread-run2 ../example/parallel_quick_sort.cpp : ex_parallel_quick_sort2 ] + #[ thread-run2 ../example/parallel_accumulate.cpp : ex_parallel_accumulate2 ] ; diff --git a/test/test_10964.cpp b/test/test_10964.cpp index a17b5691..62052fc3 100644 --- a/test/test_10964.cpp +++ b/test/test_10964.cpp @@ -77,9 +77,6 @@ int main() BOOST_STATIC_ASSERT(std::is_same > >::value); f3.wait(); } -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { auto f1 = boost::make_ready_future().then(TestCallback()); @@ -90,30 +87,17 @@ int main() BOOST_STATIC_ASSERT(std::is_same > >::value); f3.wait(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. - std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { boost::make_ready_future().then( TestCallback()).unwrap().then(TestCallback()).get(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { boost::future f = boost::async(p1); f.then( TestCallback()).unwrap().then(TestCallback()).get(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { auto f1 = boost::make_ready_future().then(TestCallback()); @@ -125,10 +109,6 @@ int main() std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; f3.wait(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { boost::basic_thread_pool executor; @@ -142,10 +122,6 @@ int main() BOOST_STATIC_ASSERT(std::is_same > >::value); f3.wait(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { boost::basic_thread_pool executor; @@ -161,10 +137,6 @@ int main() BOOST_STATIC_ASSERT(std::is_same > >::value); f3.wait(); } -#endif -#if 0 - // @fixme this doesn't works. - //Assertion failed: (future.is_ready()), function operator(), file test_10964.cpp, line 25. std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; { boost::basic_thread_pool executor; @@ -177,7 +149,6 @@ int main() BOOST_STATIC_ASSERT(std::is_same > >::value); f3.wait(); } -#endif std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; #endif