#include
#include
#include
#include
#include
#include
#include
namespace ba = boost::asio;
ba::cancellation_signal cancel_sub;
void subscribe(ba::io_context &context)
{
ba::co_spawn(
context,
[]() -> ba::awaitable { co_return; },
ba::bind_cancellation_slot(cancel_sub.slot(), ba::detached));
cancel_sub.emit(ba::cancellation_type::all);
}
int main()
{
ba::io_context ctx;
subscribe(ctx);
ctx.run();
return 0;
}
Моя программа завершает работу с исключением, выданным внутренними компонентами реализации co_await в boost:
terminate called after throwing an instance of 'boost::wrapexcept'
what(): co_await: Operation canceled [system:125]
Как этого избежать?
Я пробовал:
- Отключить исключения при отмене из сопрограммы:
- Добавив этот код в начало моей сопрограммы, чтобы включить все виды отмены:
Ничего не меняется, мое приложение все равно закрывается.
Точно, в коде boost: (помечая мои комментарии // !!! )
template
awaitable co_spawn_entry_point(
awaitable*, co_spawn_state s)
{
(void) co_await co_spawn_dispatch{};
(co_await awaitable_thread_has_context_switched{}) = false;
std::exception_ptr e = nullptr;
try
{
// !!! here an exception is thrown as the cancellation is observered.
co_await s.function();
}
catch (...)
{
// !!! caught here, all is fine
e = std::current_exception();
}
bool switched = (co_await awaitable_thread_has_context_switched{});
if (!switched)
(void) co_await co_spawn_post(); // !!! exception thrown again here as the cancellation state is checked again in await_transform! But now there is nothing to catch it...
(dispatch)(s.handler_work.get_executor(),
[handler = std::move(s.handler), e]() mutable
{
std::move(handler)(e);
});
}
Подробнее здесь: https://stackoverflow.com/questions/782 ... ermination
Мобильная версия