Reputation: 933
code snippet:
template<typename CompletionToken>
boost::awaitable<int> async_op(CompletionToken) {...}
boost::asio::cancellation_signal cancel_signal;
...
auto value = co_await async_op(boost::asio::bind_cancellation_slot(
cancel_token.slot(),
boost::asio::use_awaitable));
...
// use signal
cancel_signal.emit(boost::asio::cancellation_type::total);
I have 2 questions
thanks
Upvotes: 1
Views: 1160
Reputation: 163
I think the most basic pattern is to use the (experimental) awaitable operators, like so:
#include <boost/asio.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <iostream>
#include <thread>
namespace io = boost::asio;
using namespace boost::asio::experimental::awaitable_operators;
using namespace std::chrono_literals;
io::awaitable<void> Cancelled(io::steady_timer& cancelTimer)
{
boost::system::error_code ec;
co_await cancelTimer.async_wait(io::redirect_error(io::use_awaitable, ec));
}
io::awaitable<void> AsyncOp(io::io_context& context)
{
io::steady_timer timer{ context, 100ms };
co_await timer.async_wait(io::use_awaitable);
}
io::awaitable<void> Run(io::io_context& context, io::steady_timer& cancelTimer)
{
const auto result { co_await(AsyncOp(context) || Cancelled(cancelTimer)) };
if (result.index() == 0)
std::cout << "AsyncOp completed" << std::endl;
else
std::cout << "AsyncOp cancelled" << std::endl;
}
int main()
{
try
{
io::io_context context;
io::steady_timer cancelTimer{ context,
std::chrono::steady_clock::duration::max() };
io::co_spawn(context, Run(context, cancelTimer), io::detached);
std::future<void> contextRun{ std::async([&context] { context.run(); }) };
std::this_thread::sleep_for(10ms);
cancelTimer.cancel();
contextRun.get();
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
I highly recommend watching Talk Async.
Upvotes: 1