]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp17/coroutines_ts/range_based_for.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / asio / example / cpp17 / coroutines_ts / range_based_for.cpp
1 //
2 // range_based_for.cpp
3 // ~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2018 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/experimental/co_spawn.hpp>
12 #include <boost/asio/experimental/detached.hpp>
13 #include <boost/asio/io_context.hpp>
14 #include <boost/asio/ip/tcp.hpp>
15 #include <boost/asio/signal_set.hpp>
16 #include <boost/asio/write.hpp>
17 #include <cstdio>
18
19 using boost::asio::ip::tcp;
20 using boost::asio::experimental::awaitable;
21 using boost::asio::experimental::co_spawn;
22 using boost::asio::experimental::detached;
23 namespace this_coro = boost::asio::experimental::this_coro;
24
25 class connection_iter
26 {
27 friend class connections;
28 tcp::acceptor* acceptor_ = nullptr;
29 tcp::socket socket_;
30
31 connection_iter(tcp::acceptor& a, tcp::socket s)
32 : acceptor_(&a), socket_(std::move(s)) {}
33
34 public:
35 tcp::socket operator*()
36 {
37 return std::move(socket_);
38 }
39
40 awaitable<void> operator++()
41 {
42 auto token = co_await this_coro::token();
43 socket_ = co_await acceptor_->async_accept(token);
44 }
45
46 bool operator==(const connection_iter&) const noexcept
47 {
48 return false;
49 }
50
51 bool operator!=(const connection_iter&) const noexcept
52 {
53 return true;
54 }
55 };
56
57 class connections
58 {
59 tcp::acceptor& acceptor_;
60
61 public:
62 explicit connections(tcp::acceptor& a) : acceptor_(a) {}
63
64 awaitable<connection_iter> begin()
65 {
66 auto token = co_await this_coro::token();
67 tcp::socket s = co_await acceptor_.async_accept(token);
68 co_return connection_iter(acceptor_, std::move(s));
69 }
70
71 connection_iter end()
72 {
73 return connection_iter(acceptor_,
74 tcp::socket(acceptor_.get_executor().context()));
75 }
76 };
77
78 awaitable<void> listener(tcp::acceptor acceptor)
79 {
80 auto token = co_await this_coro::token();
81
82 for co_await (tcp::socket s : connections(acceptor))
83 {
84 co_await boost::asio::async_write(s, boost::asio::buffer("hello\r\n", 7), token);
85 }
86 }
87
88 int main()
89 {
90 try
91 {
92 boost::asio::io_context io_context(1);
93
94 boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
95 signals.async_wait([&](auto, auto){ io_context.stop(); });
96
97 tcp::acceptor acceptor(io_context, {tcp::v4(), 55555});
98 co_spawn(io_context,
99 [acceptor = std::move(acceptor)]() mutable
100 {
101 return listener(std::move(acceptor));
102 },
103 detached);
104
105 io_context.run();
106 }
107 catch (std::exception& e)
108 {
109 std::printf("Exception: %s\n", e.what());
110 }
111 }