diff --git a/include/boost/cobalt/detail/exception.hpp b/include/boost/cobalt/detail/exception.hpp index 602bfe0a..13ca43ab 100644 --- a/include/boost/cobalt/detail/exception.hpp +++ b/include/boost/cobalt/detail/exception.hpp @@ -23,6 +23,8 @@ BOOST_COBALT_DECL std::exception_ptr wait_not_ready(); BOOST_COBALT_DECL std::exception_ptr already_awaited(); BOOST_COBALT_DECL std::exception_ptr allocation_failed(); +BOOST_COBALT_DECL BOOST_NORETURN void throw_bad_executor(const boost::source_location & loc = BOOST_CURRENT_LOCATION); + template std::exception_ptr wait_not_ready() { return boost::cobalt::detail::wait_not_ready();} diff --git a/include/boost/cobalt/detail/task.hpp b/include/boost/cobalt/detail/task.hpp index 4b8d900d..05ea2e35 100644 --- a/include/boost/cobalt/detail/task.hpp +++ b/include/boost/cobalt/detail/task.hpp @@ -312,7 +312,7 @@ struct task_promise const executor_type & get_executor() const { if (!exec) - throw_exception(asio::bad_executor()); + detail::throw_bad_executor(); BOOST_ASSERT(exec_); return *exec_; } diff --git a/include/boost/cobalt/thread.hpp b/include/boost/cobalt/thread.hpp index 2150789c..5145758a 100644 --- a/include/boost/cobalt/thread.hpp +++ b/include/boost/cobalt/thread.hpp @@ -9,6 +9,7 @@ #define BOOST_COBALT_THREAD_HPP #include +#include #include @@ -56,7 +57,7 @@ struct thread { auto st = state_; if (!st || st->done) - boost::throw_exception(asio::execution::bad_executor(), loc); + cobalt::detail::throw_bad_executor(loc); return st ->ctx.get_executor(); } diff --git a/src/detail/exception.cpp b/src/detail/exception.cpp index 95effca8..f8ca2fc3 100644 --- a/src/detail/exception.cpp +++ b/src/detail/exception.cpp @@ -8,6 +8,8 @@ #include #include +#include + namespace boost::cobalt::detail { @@ -62,5 +64,14 @@ std::exception_ptr allocation_failed() return ep; } +void throw_bad_executor(const boost::source_location & loc) +{ +#if defined(BOOST_ASIO_NO_TS_EXECUTORS) + boost::throw_exception(boost::asio::execution::bad_executor(), loc); +#else + boost::throw_exception(boost::asio::bad_executor(), loc); +#endif +} + } diff --git a/src/this_thread.cpp b/src/this_thread.cpp index c8714a8c..ca233d20 100644 --- a/src/this_thread.cpp +++ b/src/this_thread.cpp @@ -6,6 +6,7 @@ // #include +#include #include #include @@ -53,7 +54,8 @@ bool has_executor() executor & get_executor(const boost::source_location & loc) { if (!detail::executor) - throw_exception(asio::bad_executor(), loc); + cobalt::detail::throw_bad_executor(loc); + return *detail::executor; } @@ -67,7 +69,8 @@ struct this_thread_service : asio::detail::execution_context_service_basecontext() == &this->context())) + + if (detail::executor && (&asio::query(*detail::executor, asio::execution::context) == &this->context())) detail::executor.reset(); } }; @@ -75,7 +78,7 @@ struct this_thread_service : asio::detail::execution_context_service_base(detail::executor->context()); + asio::use_service(asio::query(*detail::executor, asio::execution::context)); } } @@ -88,8 +91,7 @@ extract_executor(asio::any_io_executor exec) { auto t = exec.target(); if (t == nullptr) - throw_exception(asio::bad_executor()); - + cobalt::detail::throw_bad_executor(loc); return *t; } #endif diff --git a/test/promise.cpp b/test/promise.cpp index 29ef34d8..1e45db9f 100644 --- a/test/promise.cpp +++ b/test/promise.cpp @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(bad_executor_) auto t = test0(); BOOST_FAIL("Should throw"); } - catch(asio::bad_executor &) {} + catch(std::exception & e) {BOOST_CHECK_EQUAL(e.what(), std::string_view("bad executor"));} } diff --git a/test/thread.cpp b/test/thread.cpp index 9bbf9e57..d04bdfbb 100644 --- a/test/thread.cpp +++ b/test/thread.cpp @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(run) auto t = thr(); t.join(); - BOOST_CHECK_THROW(t.get_executor(), boost::asio::execution::bad_executor); + try {t.get_executor();} catch(std::exception & e) {BOOST_CHECK_EQUAL(e.what(), std::string_view("bad executor")); } } @@ -44,7 +44,7 @@ boost::cobalt::thread thr_stop() auto exc = co_await boost::asio::this_coro::executor; #endif - exc.context().stop(); + boost::asio::query(exc, boost::asio::execution::context).stop(); co_await tim.async_wait(boost::cobalt::use_op); }