From 8034c289288f051a27db2f9df65eaf9d88c47be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Tue, 16 May 2023 10:41:00 +0200 Subject: [PATCH] Propagate non-boost exceptions in concurrency code Use the existing dispatch::current_exception() workaround for boost:future's incompatibility with std::exception_ptr in more places, namely wrap any continuation call and exception handling code in rethrowing code. This is in addition to previous places, which were on the boost/pplx boundary. --- src/concurrency.h | 83 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/src/concurrency.h b/src/concurrency.h index 2c8a7e6b4d..d2f6056e15 100644 --- a/src/concurrency.h +++ b/src/concurrency.h @@ -296,6 +296,8 @@ void set_current_exception(boost::promise& pr) template void set_current_exception(std::shared_ptr> pr) { set_current_exception(*pr); } +#define RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT() catch ( ... ) { boost::rethrow_exception(dispatch::current_exception()); } + template class future_base @@ -365,7 +367,11 @@ class future : public future_base> typedef detail::continuation_calling_helper::type>::arg0_type> cch; return this->f_.then(detail::background_queue_executor::get(), [f{std::move(continuation)}](boost::future x){ - return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); + try + { + return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); }); } @@ -375,7 +381,11 @@ class future : public future_base> typedef detail::continuation_calling_helper::type>::arg0_type> cch; return this->f_.then(detail::main_thread_executor::get(), [f{std::move(continuation)}](boost::future x) { - return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); + try + { + return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); }); } @@ -386,11 +396,15 @@ class future : public future_base> wxWeakRef weak(self); return this->f_.then(detail::main_thread_executor::get(), [weak, f{std::move(continuation)}](boost::future x){ - if (weak) - return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); - else - BOOST_THROW_EXCEPTION(detail::window_dismissed()); - }); + try + { + if (weak) + return detail::call_and_unwrap_if_future(f, cch::unpack_arg(std::move(x))); + else + BOOST_THROW_EXCEPTION(detail::window_dismissed()); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); + }); }; template @@ -438,8 +452,12 @@ class future : public future_base> typedef detail::continuation_calling_helper::type>::arg0_type> cch; return this->f_.then(detail::background_queue_executor::get(), [f{std::move(continuation)}](boost::future x){ - cch::touch_arg(x); - return detail::call_and_unwrap_if_future(f); + try + { + cch::touch_arg(x); + return detail::call_and_unwrap_if_future(f); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); }); } @@ -449,8 +467,12 @@ class future : public future_base> typedef detail::continuation_calling_helper::type>::arg0_type> cch; return this->f_.then(detail::main_thread_executor::get(), [f{std::move(continuation)}](boost::future x){ - cch::touch_arg(x); - detail::call_and_unwrap_if_future(f); + try + { + cch::touch_arg(x); + detail::call_and_unwrap_if_future(f); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); }); } @@ -461,14 +483,17 @@ class future : public future_base> wxWeakRef weak(self); return this->f_.then(detail::main_thread_executor::get(), [weak, f{std::move(continuation)}](boost::future x){ - if (weak) + try { - cch::touch_arg(x); - detail::call_and_unwrap_if_future(f); + if (weak) + { + cch::touch_arg(x); + detail::call_and_unwrap_if_future(f); + } + else + BOOST_THROW_EXCEPTION(detail::window_dismissed()); } - else - BOOST_THROW_EXCEPTION(detail::window_dismissed()); - + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); }); }; @@ -497,7 +522,11 @@ auto future_base::catch_ex(F&& continuation) -> future } catch (Ex& ex) { - f(ex); + try + { + f(ex); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); } }); } @@ -517,7 +546,11 @@ auto future_base::catch_all(F&& continuation) -> future } catch (...) { - f(dispatch::current_exception()); + try + { + f(dispatch::current_exception()); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); } }); } @@ -576,7 +609,11 @@ template inline auto async(F&& f) -> future::type>::type> { return {boost::async(detail::background_queue_executor::get(), [f{std::forward(f)}]() { - return detail::call_and_unwrap_if_future(f); + try + { + return detail::call_and_unwrap_if_future(f); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); })}; } @@ -586,7 +623,11 @@ template inline auto on_main(F&& f) -> future::type>::type> { return {boost::async(detail::main_thread_executor::get(), [f{std::forward(f)}]() { - return detail::call_and_unwrap_if_future(f); + try + { + return detail::call_and_unwrap_if_future(f); + } + RETHROW_WITH_BOOST_EXCEPTION_PTR_SUPPORT(); })}; }