2
0
mirror of https://github.com/boostorg/thread.git synced 2026-01-22 05:42:37 +00:00

Take care of #10964.

This commit is contained in:
Vicente J. Botet Escriba
2015-01-24 16:48:44 +01:00
parent b77eac3e37
commit c16ec42941
2 changed files with 105 additions and 14 deletions

View File

@@ -3751,11 +3751,11 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
#if defined BOOST_THREAD_USES_MOVE
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
inline BOOST_THREAD_FUTURE<void> make_ready_future() {
promise<void> p;
p.set_value();
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
return p.get_future();
}
#endif
@@ -3765,6 +3765,43 @@ namespace detail {
p.set_exception(ex);
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
namespace detail {
template <typename R, class T>
struct make_ready_future_workaround {
template <class F>
BOOST_THREAD_FUTURE<R> operator()(BOOST_THREAD_FUTURE<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
return make_ready_future(fct(boost::move(fut)));
}
};
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
template <class T>
struct make_ready_future_workaround<void, T> {
template <class F>
BOOST_THREAD_FUTURE<void> operator()(BOOST_THREAD_FUTURE<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
fct(boost::move(fut));
return make_ready_future();
}
};
#endif
template <typename R, class T>
struct make_ready_shared_future_workaround {
template <class F>
BOOST_THREAD_FUTURE<R> operator()(shared_future<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
return make_ready_future(fct(boost::move(fut)));
}
};
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined BOOST_THREAD_USES_MOVE
template <class T>
struct make_ready_shared_future_workaround<void, T> {
template <class F>
BOOST_THREAD_FUTURE<void> operator()(shared_future<T> fut, BOOST_THREAD_FWD_REF(F) fct) {
fct(boost::move(fut));
return make_ready_future();
}
};
#endif
}
template <typename T>
BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
@@ -4340,7 +4377,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(policy) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
lock, boost::move(*this), boost::forward<F>(func)
)));
@@ -4363,9 +4404,15 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
}
}
#endif
template <typename R>
@@ -4376,7 +4423,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
lock, boost::move(*this), boost::forward<F>(func)
);
@@ -4406,7 +4457,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(policy) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
lock, boost::move(*this), boost::forward<F>(func)
)));
@@ -4430,9 +4485,15 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
}
}
#endif
template <typename R2>
@@ -4444,7 +4505,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_future_workaround<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
lock, boost::move(*this), boost::forward<F>(func)
);
@@ -4474,8 +4539,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(policy) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
lock, *this, boost::forward<F>(func)
)));
@@ -4499,9 +4567,15 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
lock, *this, boost::forward<F>(func)
)));
}
}
#endif
@@ -4514,7 +4588,11 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
if (this->is_ready(lock)) {
lock.unlock();
return boost::detail::make_ready_shared_future_workaround<typename boost::result_of<F(shared_future<R>)>::type, R>()(
boost::move(*this), boost::forward<F>(func));
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
lock, *this, boost::forward<F>(func));
} else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
@@ -4551,7 +4629,7 @@ namespace detail
: value_(v)
{}
T operator()(BOOST_THREAD_FUTURE<T> fut) {
T operator()(BOOST_THREAD_FUTURE<T> fut) const {
return fut.get_or(value_);
}
@@ -4628,6 +4706,18 @@ namespace detail
{
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (this->is_ready(lock)) {
lock.unlock();
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(this->get());
#elif defined BOOST_THREAD_USES_MOVE
BOOST_THREAD_FUTURE<R2> res = this->get();
return boost::move(res);
#else
BOOST_THREAD_FUTURE<R2> res = this->get();
return boost::move(res);
#endif
}
return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
}
#endif

View File

@@ -295,7 +295,8 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run test_9319.cpp ]
#[ thread-run test_9711.cpp ] this test is invalid and should not work :(
[ thread-run test_9856.cpp ]
[ thread-compile test_10963.cpp : : test_10963_c ]
[ thread-compile test_10963.cpp : : test_10963_c ]
[ thread-run test_10964.cpp ]
;