asio
asio copied to clipboard
cancellation_signal for co_spawn with use_future
I'm trying to bootstrap a coroutine task from a non-coroutine context, and be able to stop it from outside via a cancellation_signal:
struct Task {
void start(awaitable run);
void stop();
boost::asio::cancellation_signal signal;
}
Task::start(awaitable run) {
auto cancellable_completion = boost::asio::bind_cancellation_slot(signal.slot(), MY_COMPLETION);
auto task = boost::asio::co_spawn(io_context, run, cancellable_completion);
// ...
}
Task::stop() {
signal.emit(boost::asio::cancellation_type::all);
}
In the docs it says that the bind_xxx functions adapt a completion token to have a desired associated characteristic, so I expect to pass any completion token in place of MY_COMPLETION.
Yet I've found that passing use_future doesn't compile:
// variant 1
auto cancellable_completion = boost::asio::bind_cancellation_slot(signal.slot(), use_future);
Note that passing a callback or use_awaitable works fine:
// variant 2
auto cancellable_completion = boost::asio::bind_cancellation_slot(signal.slot(), [](std::exception_ptr) {});
// variant 3
auto cancellable_completion = boost::asio::bind_cancellation_slot(signal.slot(), use_awaitable);
I wish the future worked too, so that I could bridge it with future-based code, and be able to .wait().
Errors with use_future:
.../include/boost/asio/bind_cancellation_slot.hpp:623:34: error: no member named 'initiate' in 'boost::asio::async_result<boost::asio::use_future_t<>, void (std::exception_ptr)>'
(async_result<T, Signature>::initiate(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
.../include/boost/asio/async_result.hpp:820:12: note: expanded from macro 'BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE'
decltype expr
^~~~
.../include/boost/asio/async_result.hpp:710:5: note: in instantiation of template class 'boost::asio::async_result<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot>, void (std::exception_ptr)>' requested here
: T, async_result_memfns_base
^
.../include/boost/asio/async_result.hpp:726:8: note: in instantiation of template class 'boost::asio::detail::async_result_memfns_derived<boost::asio::async_result<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot>, void (std::exception_ptr)>>' requested here
&async_result_memfns_derived<T>::initiate>*);
^
.../include/boost/asio/async_result.hpp:730:36: note: while substituting explicitly-specified template arguments into function template 'async_result_initiate_memfn_helper'
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
^
.../include/boost/asio/async_result.hpp:871:14: note: in instantiation of template class 'boost::asio::detail::async_result_has_initiate_memfn<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &, void (std::exception_ptr)>' requested here
!detail::async_result_has_initiate_memfn<
^
.../include/boost/asio/async_result.hpp:1180:5: note: while substituting deduced template arguments into function template 'async_initiate' [with CompletionToken = boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &, Signatures = (no value), Initiation = boost::asio::detail::initiation_archetype<void (std::exception_ptr)>, Args = <>]
async_initiate<T, Signatures...>(
^
.../include/boost/asio/async_result.hpp:1180:5: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
.../include/boost/asio/async_result.hpp:1178:3: note: while substituting template arguments into constraint expression here
requires(T&& t)
^~~~~~~~~~~~~~~
.../include/boost/asio/impl/co_spawn.hpp:296:5: note: while checking the satisfaction of concept 'completion_token_for<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &, void (std::exception_ptr)>' requested here
BOOST_ASIO_COMPLETION_TOKEN_FOR(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../include/boost/asio/async_result.hpp:1185:3: note: expanded from macro 'BOOST_ASIO_COMPLETION_TOKEN_FOR'
::boost::asio::completion_token_for<sig>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../include/boost/asio/impl/co_spawn.hpp:296:5: note: while substituting template arguments into constraint expression here
BOOST_ASIO_COMPLETION_TOKEN_FOR(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../include/boost/asio/async_result.hpp:1185:18: note: expanded from macro 'BOOST_ASIO_COMPLETION_TOKEN_FOR'
::boost::asio::completion_token_for<sig>
^~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:104:14: note: while checking constraint satisfaction for template 'co_spawn<boost::asio::io_context, boost::asio::any_io_executor, boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &>' required here
auto f = boost::asio::co_spawn(
^~~~~
main:104:14: note: in instantiation of function template specialization 'boost::asio::co_spawn<boost::asio::io_context, boost::asio::any_io_executor, boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &>' requested here
In file included from main.cpp:21:
In file included from .../include/boost/asio/co_spawn.hpp:22:
In file included from .../include/boost/asio/awaitable.hpp:28:
In file included from .../include/boost/asio/any_io_executor.hpp:23:
In file included from .../include/boost/asio/execution_context.hpp:409:
In file included from .../include/boost/asio/impl/execution_context.hpp:18:
In file included from .../include/boost/asio/detail/handler_type_requirements.hpp:53:
.../include/boost/asio/async_result.hpp:663:7: error: no matching constructor for initialization of 'async_result<typename decay<cancellation_slot_binder<use_future_t<>, cancellation_slot> &>::type, void (std::exception_ptr)>' (aka 'async_result<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot>, void (std::exception_ptr)>')
result(completion_handler)
^ ~~~~~~~~~~~~~~~~~~
.../include/boost/asio/async_result.hpp:878:52: note: in instantiation of member function 'boost::asio::async_completion<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &, void (std::exception_ptr)>::async_completion' requested here
async_completion<CompletionToken, Signatures...> completion(token);
^
.../include/boost/asio/impl/co_spawn.hpp:272:10: note: in instantiation of function template specialization 'boost::asio::async_initiate<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &, void (std::exception_ptr), boost::asio::detail::initiate_co_spawn<boost::asio::any_io_executor>, boost::asio::detail::awaitable_as_function<void, boost::asio::any_io_executor>>' requested here
return async_initiate<CompletionToken, void(std::exception_ptr)>(
^
.../include/boost/asio/bind_cancellation_slot.hpp:517:12: note: candidate constructor not viable: no known conversion from 'typename conditional<is_same<cancellation_slot_binder<use_future_t<>, cancellation_slot> &, completion_handler_type>::value, completion_handler_type &, completion_handler_type>::type' (aka 'boost::asio::cancellation_slot_binder<boost::asio::detail::promise_handler<void (std::exception_ptr), std::allocator<void>>, boost::asio::cancellation_slot>') to 'cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot> &' for 1st argument
explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)
^
.../include/boost/asio/bind_cancellation_slot.hpp:681:3: note: candidate constructor not viable: no known conversion from 'typename conditional<is_same<cancellation_slot_binder<use_future_t<>, cancellation_slot> &, completion_handler_type>::value, completion_handler_type &, completion_handler_type>::type' (aka 'boost::asio::cancellation_slot_binder<boost::asio::detail::promise_handler<void (std::exception_ptr), std::allocator<void>>, boost::asio::cancellation_slot>') to 'const boost::asio::async_result<boost::asio::cancellation_slot_binder<boost::asio::use_future_t<>, boost::asio::cancellation_slot>, void (std::exception_ptr)>' for 1st argument
async_result(const async_result&) BOOST_ASIO_DELETED;
^
I'm using asio from boost 1.78. Compiling using Apple clang version 13.1.6 (clang-1316.0.21.2) from Xcode 13 on macOS 12.4.