2

Lets say for example I have a boost::asio::steady_timer timer that I want to async wait on with boost::asio::steady_timer::async_wait. In the old way I get errors as code parameter in my completion handler i.e. my lambda like

timer.async_wait([](const auto &boost_error) {
            //check boost_error
        });

With Co routines I am able to co_await when using boost::asio::use_awaitable as

co_await timer.async_wait(boost::asio::use_awaitable);

However the error handling has changed: In order to catch errors, like an canceled timer, I have to wrap my co_await in a try/catch block.

Can I get boost to let me await on the async operation but giving me the error as a code, like

 std::variant<void, error_code> = co_await timer.async_wait(boost::asio::use_awaitable);

?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Superlokkus
  • 4,731
  • 1
  • 25
  • 57

1 Answers1

2

Close: as_tuple(use_awaitable) works almost exactly like that:

Live On Compiler Explorer

#include <boost/asio.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace std::chrono_literals;
using namespace asio::experimental::awaitable_operators;

asio::awaitable<void> timer(auto duration) {
    auto [ec] = co_await asio::steady_timer{co_await asio::this_coro::executor, duration}.async_wait(
        as_tuple(asio::use_awaitable));
    std::cout << "Wait for " << (duration / 1.s) << "s: " << ec.message() << std::endl;
};

int main() {
    asio::io_context ioc;
    asio::co_spawn(ioc, timer(3s) || timer(1500ms), asio::detached);

    ioc.run();
}

Prints:

Wait for 1.5s: Success
Wait for 3s: Operation canceled

Alternative adaptors: asio::redirect_error and asio::as_single

sehe
  • 374,641
  • 47
  • 450
  • 633
  • As always: Many thanks, you seem to be always exactly one step ahead :-). Nitpick: Could you give examples with the redirect error? Now I know what to try, but I you want to write the perfect answer, you know ;-). – Superlokkus Aug 17 '23 at 14:41
  • 1
    I just made one here: https://stackoverflow.com/a/76922642/85371 – sehe Aug 17 '23 at 14:47
  • I see thank you. To my defense: In hind sight, it's always logical with boost, and elegant with all that meta programming, but with just lofty concepts, >7 overloads + meta programming I would say its sometimes hard to understand the implications out from the documentation. Until next time, I hope the day will come where I answer a question of yours :-) – Superlokkus Aug 17 '23 at 14:55
  • I see thank you. To my defense: In hind sight, it's always logical with boost, and elegant with all that meta programming, but with just lofty concepts, >7 overloads + meta programming I would say its sometimes hard to understand the implications out from the documentation. Until next time, I hope the day will come where I answer a question of yours :-) – Superlokkus Aug 17 '23 at 14:57
  • 1
    No need to defend :) As you note, I'm only just a step ahead on the same hill! – sehe Aug 17 '23 at 14:59