diff --git a/include/ylt/coro_io/coro_io.hpp b/include/ylt/coro_io/coro_io.hpp index 058ffb730..d60b08f4d 100644 --- a/include/ylt/coro_io/coro_io.hpp +++ b/include/ylt/coro_io/coro_io.hpp @@ -25,6 +25,7 @@ #endif #include +#include #include #include #include @@ -282,20 +283,42 @@ inline async_simple::coro::Lazy sleep_for(Duration d) { } } -template -inline async_simple::coro::Lazy post( - Func func, - coro_io::ExecutorWrapper<> *e = coro_io::get_global_block_executor()) { - callback_awaitor awaitor; - - co_return co_await awaitor.await_resume( - [e, func = std::move(func)](auto handler) { - auto executor = e->get_asio_executor(); - asio::post(executor, [=, func = std::move(func)]() { +template +struct post_helper { + void operator()(auto handler) const { + asio::dispatch(e->get_asio_executor(), [this, handler]() { + try { + if constexpr (std::is_same_v>) { func(); handler.resume(); - }); - }); + } + else { + auto r = func(); + handler.set_value_then_resume(std::move(r)); + } + } catch (const std::exception &e) { + R er; + er.setException(std::current_exception()); + handler.set_value_then_resume(std::move(er)); + } + }); + } + coro_io::ExecutorWrapper<> *e; + Func func; +}; + +template +inline async_simple::coro::Lazy< + async_simple::Try::return_type>> +post(Func func, + coro_io::ExecutorWrapper<> *e = coro_io::get_global_block_executor()) { + using R = + async_simple::Try::return_type>; + + callback_awaitor awaitor; + + post_helper helper{e, std::move(func)}; + co_return co_await awaitor.await_resume(helper); } template