Line data Source code
1 : #ifndef THINGER_ASIO_WITH_TIMEOUT_HPP
2 : #define THINGER_ASIO_WITH_TIMEOUT_HPP
3 :
4 : #include <chrono>
5 : #include <optional>
6 : #include <utility>
7 : #include <variant>
8 : #include <boost/asio/steady_timer.hpp>
9 : #include <boost/asio/this_coro.hpp>
10 : #include "../util/types.hpp"
11 :
12 : namespace thinger::asio {
13 :
14 : // The result of `operation`, or nothing if it did not complete within `timeout`: it is then
15 : // cancelled (per-operation cancellation, as the awaitable operators do, see socket.hpp).
16 : // Both the operation and the timer end before this returns, so nothing outlives the call
17 : // (unlike a timer detached from the caller, which may still run once the caller is gone).
18 : // The timer runs on the executor of the caller
19 : template<typename T>
20 9785 : awaitable<std::optional<T>> with_timeout(awaitable<T> operation, std::chrono::steady_clock::duration timeout) {
21 : boost::asio::steady_timer timer(co_await boost::asio::this_coro::executor, timeout);
22 : auto result = co_await (std::move(operation) || timer.async_wait(use_nothrow_awaitable));
23 : if (result.index() == 0) co_return std::optional<T>{std::get<0>(std::move(result))};
24 : co_return std::nullopt;
25 19570 : }
26 :
27 : }
28 :
29 : #endif
|