I'm currently working on a project that uses boost asio for networking. I want to implement a function that look like this:
template<command T, response R = typename T::response_type>
auto send_command(T c) -> boost::asio::awaitable<R> {
// ...
}
In my code, when I'm writing the command to the socket, I will eventually receive a response with the result. I may receive any number of other responses in the socket before getting the response to a specific command.
I figured I could use async_initiate to make sending a command an asynchronous operation composed of a write and a read.
I've already used async_initiate to start asynchronous operations, but it was of the type boost::asio::awaitable<void>. And the code looked like this:
// returns the awaitable for the coroutine to suspend
return asio::async_initiate<CompletionToken, void(void)>(
[self = shared_from_this()](auto&& handler) {
self->callback_queue.push(std::forward<decltype(handler)>(handler));
}
);
// later
auto& resume = callback_queue.front();
resume(); // resume the suspended coroutine
But I can't figure where to put the return value here when It's not void!
auto const command_id = std::int32_t{...};
auto& resume_command = commands_continuations[command_id];
resume_command(response_result); // Send the `co_await` result in parameters??
I'm simply confused how to send the return of the awaitable and how to initiate the asynchronous operation with a result.