mirror of
https://github.com/boostorg/thread.git
synced 2026-02-04 22:02:10 +00:00
Compare commits
2 Commits
feature/ex
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69c1d40750 | ||
|
|
952aa44a98 |
@@ -432,24 +432,24 @@ namespace boost
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
void mark_interrupted_finish()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
exception = boost::copy_exception(boost::thread_interrupted());
|
||||
mark_finished_internal(lock);
|
||||
}
|
||||
// void mark_interrupted_finish()
|
||||
// {
|
||||
// boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
// exception = boost::copy_exception(boost::thread_interrupted());
|
||||
// mark_finished_internal(lock);
|
||||
// }
|
||||
|
||||
void set_interrupted_at_thread_exit()
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (has_value(lk))
|
||||
{
|
||||
throw_exception(promise_already_satisfied());
|
||||
}
|
||||
exception = boost::copy_exception(boost::thread_interrupted());
|
||||
this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
// void set_interrupted_at_thread_exit()
|
||||
// {
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (has_value(lk))
|
||||
// {
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// }
|
||||
// exception = boost::copy_exception(boost::thread_interrupted());
|
||||
// this->is_constructed = true;
|
||||
// detail::make_ready_at_thread_exit(shared_from_this());
|
||||
// }
|
||||
#endif
|
||||
|
||||
void set_exception_at_thread_exit(exception_ptr e)
|
||||
@@ -481,14 +481,14 @@ namespace boost
|
||||
return done && exception;
|
||||
}
|
||||
|
||||
bool has_exception(unique_lock<boost::mutex>&) const
|
||||
{
|
||||
return done && exception;
|
||||
}
|
||||
// bool has_exception(unique_lock<boost::mutex>&) const
|
||||
// {
|
||||
// return done && exception;
|
||||
// }
|
||||
|
||||
bool is_deferred(boost::lock_guard<boost::mutex>&) const {
|
||||
return is_deferred_;
|
||||
}
|
||||
// bool is_deferred(boost::lock_guard<boost::mutex>&) const {
|
||||
// return is_deferred_;
|
||||
// }
|
||||
|
||||
launch launch_policy(boost::unique_lock<boost::mutex>&) const
|
||||
{
|
||||
@@ -511,13 +511,14 @@ namespace boost
|
||||
exception_ptr get_exception_ptr()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
return get_exception_ptr(lock);
|
||||
}
|
||||
exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
|
||||
{
|
||||
wait_internal(lock, false);
|
||||
return exception;
|
||||
}
|
||||
// exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
|
||||
// {
|
||||
// wait_internal(lock, false);
|
||||
// return exception;
|
||||
// }
|
||||
|
||||
template<typename F,typename U>
|
||||
void set_wait_callback(F f,U* u)
|
||||
@@ -580,21 +581,29 @@ namespace boost
|
||||
|
||||
void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
result = boost::move(result_);
|
||||
#else
|
||||
#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
result.reset(new T(boost::move(result_)));
|
||||
#endif
|
||||
#else
|
||||
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
result = boost::move(result_);
|
||||
#else
|
||||
result.reset(new T(static_cast<rvalue_source_type>(result_)));
|
||||
#endif
|
||||
this->mark_finished_internal(lock);
|
||||
}
|
||||
|
||||
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class ...Args>
|
||||
void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock, BOOST_THREAD_FWD_REF(Args)... args)
|
||||
{
|
||||
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
result.emplace(boost::forward<Args>(args)...);
|
||||
#else
|
||||
result.reset(new T(boost::forward<Args>(args)...));
|
||||
#endif
|
||||
this->mark_finished_internal(lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
void mark_finished_with_result(source_reference_type result_)
|
||||
{
|
||||
@@ -830,12 +839,6 @@ namespace boost
|
||||
{
|
||||
that->mark_finished_with_result(f());
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
that->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
that->mark_exceptional_finish();
|
||||
@@ -858,12 +861,6 @@ namespace boost
|
||||
f();
|
||||
that->mark_finished_with_result();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
that->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
that->mark_exceptional_finish();
|
||||
@@ -885,12 +882,6 @@ namespace boost
|
||||
{
|
||||
that->mark_finished_with_result(f());
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
that->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
that->mark_exceptional_finish();
|
||||
@@ -1277,7 +1268,6 @@ namespace boost
|
||||
future_ = p.get_future().future_;
|
||||
}
|
||||
|
||||
|
||||
future_ptr future_;
|
||||
|
||||
basic_future(future_ptr a_future):
|
||||
@@ -2077,6 +2067,22 @@ namespace boost
|
||||
future_->mark_finished_with_result_internal(static_cast<rvalue_source_type>(r), lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class ...Args>
|
||||
void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
|
||||
{
|
||||
lazy_init();
|
||||
boost::unique_lock<boost::mutex> lock(future_->mutex);
|
||||
if(future_->done)
|
||||
{
|
||||
boost::throw_exception(promise_already_satisfied());
|
||||
}
|
||||
future_->mark_finished_with_result_internal(lock, boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void set_exception(boost::exception_ptr p)
|
||||
{
|
||||
lazy_init();
|
||||
@@ -2606,12 +2612,12 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2637,12 +2643,6 @@ namespace boost
|
||||
this->mark_finished_with_result(f());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
@@ -2693,12 +2693,12 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2720,12 +2720,6 @@ namespace boost
|
||||
R& res((f()));
|
||||
this->mark_finished_with_result(res);
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
@@ -2783,12 +2777,12 @@ namespace boost
|
||||
this->set_value_at_thread_exit(boost::move(r));
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2811,12 +2805,6 @@ namespace boost
|
||||
R res((f()));
|
||||
this->mark_finished_with_result(boost::move(res));
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
@@ -2870,12 +2858,12 @@ namespace boost
|
||||
this->set_value_at_thread_exit(f());
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2897,12 +2885,6 @@ namespace boost
|
||||
{
|
||||
this->mark_finished_with_result(f());
|
||||
}
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
@@ -2953,12 +2935,12 @@ namespace boost
|
||||
#endif
|
||||
this->set_value_at_thread_exit();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -2980,12 +2962,6 @@ namespace boost
|
||||
#endif
|
||||
this->mark_finished_with_result();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
this->mark_exceptional_finish();
|
||||
@@ -3032,12 +3008,12 @@ namespace boost
|
||||
#endif
|
||||
this->set_value_at_thread_exit();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->set_interrupted_at_thread_exit();
|
||||
}
|
||||
#endif
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// catch(thread_interrupted& )
|
||||
// {
|
||||
// this->set_interrupted_at_thread_exit();
|
||||
// }
|
||||
//#endif
|
||||
catch(...)
|
||||
{
|
||||
this->set_exception_at_thread_exit(current_exception());
|
||||
@@ -3059,12 +3035,6 @@ namespace boost
|
||||
#endif
|
||||
this->mark_finished_with_result();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
#endif
|
||||
catch(...)
|
||||
{
|
||||
this->mark_exceptional_finish();
|
||||
@@ -3602,10 +3572,6 @@ namespace detail {
|
||||
void operator()() {
|
||||
try {
|
||||
that->mark_finished_with_result(f_());
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -3653,10 +3619,6 @@ namespace detail {
|
||||
try {
|
||||
f_();
|
||||
that->mark_finished_with_result();
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -3702,10 +3664,6 @@ namespace detail {
|
||||
void operator()() {
|
||||
try {
|
||||
that->mark_finished_with_result(f_());
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif // defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -3929,7 +3887,11 @@ namespace detail {
|
||||
////////////////////////////////
|
||||
// make_ready_future
|
||||
////////////////////////////////
|
||||
template <typename T>
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <int = 0, int..., class T>
|
||||
#else
|
||||
template <class T>
|
||||
#endif
|
||||
BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value) {
|
||||
typedef typename decay<T>::type future_value_type;
|
||||
promise<future_value_type> p;
|
||||
@@ -3937,6 +3899,35 @@ namespace detail {
|
||||
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
|
||||
}
|
||||
|
||||
// explicit overloads
|
||||
template <class T>
|
||||
BOOST_THREAD_FUTURE<T> make_ready_future(typename remove_reference<T>::type & x)
|
||||
{
|
||||
promise<T> p;
|
||||
p.set_value(x);
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BOOST_THREAD_FUTURE<T> make_ready_future(BOOST_THREAD_FWD_REF(typename remove_reference<T>::type) x)
|
||||
{
|
||||
promise<T> p;
|
||||
p.set_value(forward<typename remove_reference<T>::type>(x));
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
// variadic overload
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class T, class ...Args>
|
||||
BOOST_THREAD_FUTURE<T> make_ready_future(Args&&... args)
|
||||
{
|
||||
promise<T> p;
|
||||
p.emplace(forward<Args>(args)...);
|
||||
return p.get_future();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T, typename T1>
|
||||
BOOST_THREAD_FUTURE<T> make_ready_no_decay_future(T1 value) {
|
||||
typedef T future_value_type;
|
||||
@@ -4052,10 +4043,6 @@ namespace detail
|
||||
static void run(future_async_continuation_shared_state* that) {
|
||||
try {
|
||||
that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4086,10 +4073,6 @@ namespace detail
|
||||
try {
|
||||
that->continuation(boost::move(that->parent));
|
||||
that->mark_finished_with_result();
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4135,10 +4118,6 @@ namespace detail
|
||||
static void run(future_executor_continuation_shared_state* that) {
|
||||
try {
|
||||
that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4172,10 +4151,6 @@ namespace detail
|
||||
try {
|
||||
that->continuation(boost::move(that->parent));
|
||||
that->mark_finished_with_result();
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4210,10 +4185,6 @@ namespace detail
|
||||
static void run(shared_future_async_continuation_shared_state* that) {
|
||||
try {
|
||||
that->mark_finished_with_result(that->continuation(that->parent));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4244,10 +4215,6 @@ namespace detail
|
||||
try {
|
||||
that->continuation(that->parent);
|
||||
that->mark_finished_with_result();
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4285,10 +4252,6 @@ namespace detail
|
||||
static void run(shared_future_executor_continuation_shared_state* that) {
|
||||
try {
|
||||
that->mark_finished_with_result(that->continuation(that->parent));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4321,10 +4284,6 @@ namespace detail
|
||||
try {
|
||||
that->continuation(that->parent);
|
||||
that->mark_finished_with_result();
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4811,10 +4770,6 @@ namespace detail
|
||||
try {
|
||||
boost::wait_for_all(that->vec_.begin(), that->vec_.end());
|
||||
that->mark_finished_with_result(boost::move(that->vec_));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4885,10 +4840,6 @@ namespace detail
|
||||
try {
|
||||
boost::wait_for_any(that->vec_.begin(), that->vec_.end());
|
||||
that->mark_finished_with_result(boost::move(that->vec_));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -4993,10 +4944,6 @@ namespace detail
|
||||
that->wait_for_all(Index());
|
||||
|
||||
that->mark_finished_with_result(boost::move(that->tup_));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
@@ -5067,10 +5014,6 @@ namespace detail
|
||||
that->wait_for_any(Index());
|
||||
|
||||
that->mark_finished_with_result(boost::move(that->tup_));
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
} catch(thread_interrupted& ) {
|
||||
that->mark_interrupted_finish();
|
||||
#endif
|
||||
} catch(...) {
|
||||
that->mark_exceptional_finish();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace boost
|
||||
/// Effect: Decrement the count. Unlocks the lock and notify anyone waiting if we reached zero.
|
||||
/// Returns: true if count_ reached the value 0.
|
||||
/// @ThreadSafe ensured by the @c lk parameter
|
||||
bool count_down(unique_lock<mutex> &lk)
|
||||
bool count_down(unique_lock<mutex> &)
|
||||
/// pre_condition (count_ > 0)
|
||||
{
|
||||
BOOST_ASSERT(count_ > 0);
|
||||
|
||||
@@ -349,6 +349,7 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run2-noit ./sync/futures/promise/set_rvalue_pass.cpp : promise__set_rvalue_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/set_value_const_pass.cpp : promise__set_value_const_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/set_value_void_pass.cpp : promise__set_value_void_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/emplace_pass.cpp : promise__emplace_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/set_exception_at_thread_exit_pass.cpp : promise__set_exception_at_thread_exit_p ]
|
||||
[ thread-run2-noit ./sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp : promise__set_lvalue_at_thread_exit_p ]
|
||||
@@ -357,6 +358,12 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run2-noit ./sync/futures/promise/set_value_at_thread_exit_void_pass.cpp : promise__set_value_at_thread_exit_void_p ]
|
||||
;
|
||||
|
||||
#explicit ts_make_ready_future ;
|
||||
test-suite ts_make_ready_future
|
||||
:
|
||||
[ thread-run2-noit ./sync/futures/make_ready_future_pass.cpp : make_ready_future_p ]
|
||||
;
|
||||
|
||||
#explicit ts_future ;
|
||||
test-suite ts_future
|
||||
:
|
||||
|
||||
157
test/sync/futures/make_ready_future_pass.cpp
Normal file
157
test/sync/futures/make_ready_future_pass.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (C) 2011,2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
// <boost/thread/future.hpp>
|
||||
|
||||
// class promise<R>
|
||||
|
||||
// future<void> make_ready_future();
|
||||
// template <class T>
|
||||
// future<decay_t<T>> make_ready_future(T&&);
|
||||
// template <class T>
|
||||
// future<T> make_ready_future(remove_reference_t<T>&);
|
||||
// template <class T>
|
||||
// future<T> make_ready_future(remove_reference_t<T>&&);
|
||||
// template <class T, class ...Args>
|
||||
// future<T> make_ready_future(Args&& ... args);
|
||||
|
||||
#define BOOST_THREAD_VERSION 3
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
struct A
|
||||
{
|
||||
A() :
|
||||
value(0)
|
||||
{
|
||||
}
|
||||
A(int i) :
|
||||
value(i)
|
||||
{
|
||||
}
|
||||
A(int i, int j) :
|
||||
value(i+j)
|
||||
{
|
||||
}
|
||||
int value;
|
||||
};
|
||||
|
||||
A make(int i) {
|
||||
return A(i);
|
||||
}
|
||||
A make(int i, int j) {
|
||||
return A(i, j);
|
||||
}
|
||||
|
||||
struct movable2
|
||||
{
|
||||
int value_;
|
||||
BOOST_THREAD_MOVABLE_ONLY(movable2)
|
||||
movable2() : value_(1){}
|
||||
movable2(int i) : value_(i){}
|
||||
movable2(int i, int j) : value_(i+j){}
|
||||
|
||||
//Move constructor and assignment
|
||||
movable2(BOOST_RV_REF(movable2) m)
|
||||
{ value_ = m.value_; m.value_ = 0; }
|
||||
|
||||
movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
|
||||
{ value_ = m.value_; m.value_ = 0; return *this; }
|
||||
|
||||
bool moved() const //Observer
|
||||
{ return !value_; }
|
||||
|
||||
int value() const //Observer
|
||||
{ return value_; }
|
||||
};
|
||||
|
||||
|
||||
movable2 move_return_function2(int i) {
|
||||
return movable2(i);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
|
||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
|
||||
BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == true));
|
||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == false));
|
||||
#endif
|
||||
|
||||
{
|
||||
boost::future<void> f = boost::make_ready_future();
|
||||
f.wait();
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
T i;
|
||||
boost::future<T> f = boost::make_ready_future(i);
|
||||
BOOST_TEST(f.get().value==0);
|
||||
}
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
{
|
||||
typedef A T;
|
||||
boost::future<T> f = boost::make_ready_future<T>();
|
||||
BOOST_TEST(f.get().value==0);
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
boost::future<T> f = boost::make_ready_future<T>(1);
|
||||
BOOST_TEST(f.get().value==1);
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
boost::future<T> f = boost::make_ready_future<T>(1,2);
|
||||
BOOST_TEST(f.get().value==3);
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
T i;
|
||||
boost::future<T&> f = boost::make_ready_future<T&>(i);
|
||||
BOOST_TEST(f.get().value==0);
|
||||
}
|
||||
#endif
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
// sync/futures/make_ready_future_pass.cpp:125:65: erreur: conversion from Ôboost::future<boost::rv<movable2> >Õ to non-scalar type Ôboost::future<movable2>Õ requested
|
||||
{
|
||||
typedef movable2 T;
|
||||
T i;
|
||||
boost::future<T> f = boost::make_ready_future(boost::move(i));
|
||||
BOOST_TEST_EQ(f.get().value(),1);
|
||||
}
|
||||
#endif
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
{
|
||||
typedef movable2 T;
|
||||
boost::future<T> f = boost::make_ready_future<T>();
|
||||
BOOST_TEST(f.get().value()==1);
|
||||
}
|
||||
{
|
||||
typedef movable2 T;
|
||||
boost::future<T> f = boost::make_ready_future<T>(1);
|
||||
BOOST_TEST(f.get().value()==1);
|
||||
}
|
||||
{
|
||||
typedef movable2 T;
|
||||
boost::future<T> f = boost::make_ready_future<T>(1,2);
|
||||
BOOST_TEST(f.get().value()==3);
|
||||
}
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
207
test/sync/futures/promise/emplace_pass.cpp
Normal file
207
test/sync/futures/promise/emplace_pass.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Copyright (C) 2011,2014 Vicente J. Botet Escriba
|
||||
//
|
||||
// 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)
|
||||
|
||||
// <boost/thread/future.hpp>
|
||||
|
||||
// class promise<R>
|
||||
|
||||
// template <class ...Args>
|
||||
// void promise::emplace(Args&& ... args);
|
||||
|
||||
#define BOOST_THREAD_VERSION 3
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
struct A
|
||||
{
|
||||
A() :
|
||||
value(0)
|
||||
{
|
||||
}
|
||||
A(int i) :
|
||||
value(i)
|
||||
{
|
||||
}
|
||||
A(int i, int j) :
|
||||
value(i+j)
|
||||
{
|
||||
}
|
||||
BOOST_THREAD_MOVABLE_ONLY(A)
|
||||
|
||||
A(BOOST_THREAD_RV_REF(A) rhs)
|
||||
{
|
||||
if(rhs.value==0)
|
||||
throw 9;
|
||||
else
|
||||
{
|
||||
value=rhs.value;
|
||||
rhs.value=0;
|
||||
}
|
||||
}
|
||||
A& operator=(BOOST_THREAD_RV_REF(A) rhs)
|
||||
{
|
||||
if(rhs.value==0)
|
||||
throw 9;
|
||||
else
|
||||
{
|
||||
value=rhs.value;
|
||||
rhs.value=0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
int value;
|
||||
};
|
||||
|
||||
A make(int i) {
|
||||
return A(i);
|
||||
}
|
||||
A make(int i, int j) {
|
||||
return A(i, j);
|
||||
}
|
||||
|
||||
struct movable2
|
||||
{
|
||||
int value_;
|
||||
BOOST_THREAD_MOVABLE_ONLY(movable2)
|
||||
movable2() : value_(1){}
|
||||
movable2(int i) : value_(i){}
|
||||
movable2(int i, int j) : value_(i+j){}
|
||||
|
||||
//Move constructor and assignment
|
||||
movable2(BOOST_RV_REF(movable2) m)
|
||||
{ value_ = m.value_; m.value_ = 0; }
|
||||
|
||||
movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
|
||||
{ value_ = m.value_; m.value_ = 0; return *this; }
|
||||
|
||||
bool moved() const //Observer
|
||||
{ return !value_; }
|
||||
|
||||
int value() const //Observer
|
||||
{ return value_; }
|
||||
};
|
||||
|
||||
|
||||
movable2 move_return_function2(int i) {
|
||||
return movable2(i);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
|
||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
|
||||
BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
|
||||
BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
|
||||
#endif
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
{
|
||||
typedef A T;
|
||||
T i;
|
||||
boost::promise<T> p;
|
||||
boost::future<T> f = p.get_future();
|
||||
p.emplace();
|
||||
try
|
||||
{
|
||||
T a = f.get(); (void)a;
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (int j)
|
||||
{
|
||||
BOOST_TEST(j == 9);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
boost::promise<T> p;
|
||||
boost::future<T> f = p.get_future();
|
||||
p.emplace(3);
|
||||
BOOST_TEST(f.get().value == 3);
|
||||
try
|
||||
{
|
||||
T j(3);
|
||||
p.set_value(boost::move(j));
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (const boost::future_error& e)
|
||||
{
|
||||
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
boost::promise<movable2> p;
|
||||
boost::future<movable2> f = p.get_future();
|
||||
p.emplace(3);
|
||||
BOOST_TEST(f.get().value_ == 3);
|
||||
try
|
||||
{
|
||||
p.emplace(3);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (const boost::future_error& e)
|
||||
{
|
||||
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
boost::promise<A> p;
|
||||
boost::future<A> f = p.get_future();
|
||||
p.emplace(1,2);
|
||||
BOOST_TEST(f.get().value == 3);
|
||||
try
|
||||
{
|
||||
p.emplace(1,2);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch (const boost::future_error& e)
|
||||
{
|
||||
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
typedef A T;
|
||||
boost::promise<T> p;
|
||||
boost::future<T> f = p.get_future();
|
||||
p.emplace(3);
|
||||
boost::promise<T> p2(boost::move(p));
|
||||
BOOST_TEST(f.get().value == 3);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user