1//
2// timeout.cpp
3// ~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#include <boost/asio.hpp>
12#include <boost/asio/experimental/awaitable_operators.hpp>
13
14using namespace boost::asio;
15using namespace boost::asio::experimental::awaitable_operators;
16using time_point = std::chrono::steady_clock::time_point;
17using ip::tcp;
18
19awaitable<void> echo(tcp::socket& sock, time_point& deadline)
20{
21 char data[4196];
22 for (;;)
23 {
24 deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
25 auto n = co_await sock.async_read_some(buffer(data), use_awaitable);
26 co_await async_write(sock, buffer(data, n), use_awaitable);
27 }
28}
29
30awaitable<void> watchdog(time_point& deadline)
31{
32 steady_timer timer(co_await this_coro::executor);
33 auto now = std::chrono::steady_clock::now();
34 while (deadline > now)
35 {
36 timer.expires_at(deadline);
37 co_await timer.async_wait(use_awaitable);
38 now = std::chrono::steady_clock::now();
39 }
40 throw boost::system::system_error(std::make_error_code(e: std::errc::timed_out));
41}
42
43awaitable<void> handle_connection(tcp::socket sock)
44{
45 time_point deadline{};
46 co_await (echo(sock, deadline) && watchdog(deadline));
47}
48
49awaitable<void> listen(tcp::acceptor& acceptor)
50{
51 for (;;)
52 {
53 co_spawn(
54 acceptor.get_executor(),
55 handle_connection(co_await acceptor.async_accept(use_awaitable)),
56 detached);
57 }
58}
59
60int main()
61{
62 io_context ctx;
63 tcp::acceptor acceptor(ctx, {tcp::v4(), 54321});
64 co_spawn(ctx, listen(acceptor), detached);
65 ctx.run();
66}
67

source code of boost/libs/asio/example/cpp20/coroutines/timeout.cpp