include/boost/corosio/native/detail/reactor/reactor_backend.hpp

95.4% Lines (83 / 87) 30.3% Branches (40 / 132) 100.0% Functions (4 / 4)
reactor_backend.hpp
f(x) Functions (4)
Function Calls Lines Branches Blocks
boost::corosio::detail::reactor_acceptor_impl<boost::corosio::detail::kqueue_local_stream_acceptor, boost::corosio::detail::kqueue_traits, boost::corosio::detail::kqueue_local_stream_acceptor_service, boost::corosio::detail::kqueue_local_stream_socket, boost::corosio::local_stream_acceptor::implementation, boost::corosio::local_endpoint>::accept(boost::capy::continuation&, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 23x 100.0% – 36.0% boost::corosio::detail::reactor_acceptor_impl<boost::corosio::detail::kqueue_tcp_acceptor, boost::corosio::detail::kqueue_traits, boost::corosio::detail::kqueue_tcp_acceptor_service, boost::corosio::detail::kqueue_tcp_socket, boost::corosio::tcp_acceptor::implementation, boost::corosio::endpoint>::accept(boost::capy::continuation&, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 8702x 66.3% 37.5% 80.0% boost::corosio::detail::reactor_acceptor_impl<boost::corosio::detail::select_local_stream_acceptor, boost::corosio::detail::select_traits, boost::corosio::detail::select_local_stream_acceptor_service, boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_acceptor::implementation, boost::corosio::local_endpoint>::accept(boost::capy::continuation&, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 22x 49.4% 15.9% 35.0% boost::corosio::detail::reactor_acceptor_impl<boost::corosio::detail::select_tcp_acceptor, boost::corosio::detail::select_traits, boost::corosio::detail::select_tcp_acceptor_service, boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_acceptor::implementation, boost::corosio::endpoint>::accept(boost::capy::continuation&, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 6609x 95.4% 60.6% 58.0%
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
12
13 /* Reactor backend: acceptor accept() implementation.
14
15 Contains the accept() method body for reactor_acceptor_impl,
16 which needs all socket/service types to be complete. Included
17 by per-backend type files (epoll_types.hpp, etc.) after all
18 named types are defined.
19 */
20
21 #include <boost/corosio/native/detail/reactor/reactor_service_finals.hpp>
22 #include <boost/corosio/native/detail/reactor/reactor_op_complete.hpp>
23 #include <boost/corosio/native/detail/endpoint_convert.hpp>
24 #include <boost/corosio/detail/dispatch_coro.hpp>
25
26 #include <mutex>
27
28 namespace boost::corosio::detail {
29
30 // ============================================================
31 // Acceptor accept() implementation
32 // ============================================================
33
34 template<
35 class Derived,
36 class Traits,
37 class Service,
38 class SocketFinal,
39 class AccImplBase,
40 class Endpoint>
41 std::coroutine_handle<>
42 reactor_acceptor_impl<
43 Derived,
44 Traits,
45 Service,
46 SocketFinal,
47 AccImplBase,
48 Endpoint>::
49 15356x accept(
50 capy::continuation& cont,
51 capy::executor_ref ex,
52 std::stop_token token,
53 std::error_code* ec,
54 io_object::implementation** impl_out)
55 {
56 15356x auto& op = this->acc_;
57 15356x op.reset();
58 15356x op.cont = &cont;
59 15356x op.ex = ex;
60 15356x op.ec_out = ec;
61 15356x op.impl_out = impl_out;
62 15356x op.fd = this->fd_;
63 15356x op.start(token, static_cast<Derived*>(this));
64
65 15356x sockaddr_storage peer_storage{};
66 15356x socklen_t peer_addrlen = 0;
67
68 15356x int accepted =
69 15356x Traits::accept_policy::do_accept(this->fd_, peer_storage, peer_addrlen);
70
71
4/8
✓ Branch 0 taken 7866 times.
✓ Branch 1 taken 859 times.
✓ Branch 2 taken 5067 times.
✓ Branch 3 taken 1564 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15356x if (accepted >= 0)
72 {
73 {
74 2423x std::lock_guard lock(this->desc_state_.mutex);
75 2423x this->desc_state_.read_ready = false;
76 2423x }
77
78
4/8
✓ Branch 0 taken 810 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 1442 times.
✓ Branch 3 taken 122 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2423x if (this->svc_.scheduler().try_consume_inline_budget())
79 {
80 2252x auto* socket_svc = this->svc_.stream_service();
81
2/8
✓ Branch 0 taken 810 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1442 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2252x if (socket_svc)
82 {
83 2252x auto& impl =
84 2252x static_cast<SocketFinal&>(*socket_svc->construct());
85 4504x impl.set_socket(
86 2252x accepted,
87
2/8
✓ Branch 0 taken 810 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1442 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2252x peer_addrlen > 0 ? peer_storage.ss_family : AF_UNSPEC);
88
89 2252x impl.desc_state_.fd = accepted;
90 {
91 2252x std::lock_guard lock(impl.desc_state_.mutex);
92 2252x impl.desc_state_.read_op = nullptr;
93 2252x impl.desc_state_.write_op = nullptr;
94 2252x impl.desc_state_.connect_op = nullptr;
95 2252x }
96 4504x auto reg_ec = socket_svc->scheduler().register_descriptor(
97 2252x accepted, &impl.desc_state_);
98
3/8
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 809 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1442 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2252x if (reg_ec)
99 {
100 // destroy() closes the fd the impl already owns.
101 1x socket_svc->destroy(&impl);
102 1x *ec = reg_ec;
103
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1x if (impl_out)
104 1x *impl_out = nullptr;
105 1x }
106 else
107 {
108 4502x impl.set_endpoints(
109 2251x this->local_endpoint_,
110 2251x from_sockaddr_as(
111 2251x peer_storage, peer_addrlen, Endpoint{}));
112
113 2251x *ec = {};
114
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 809 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1442 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2251x if (impl_out)
115 2251x *impl_out = &impl;
116 }
117 2252x }
118 else
119 {
120 ✗ ::close(accepted);
121 ✗ *ec = make_err(ENOENT);
122
0/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ if (impl_out)
123 ✗ *impl_out = nullptr;
124 }
125 // Completed without parking: nothing left for a stop to cancel.
126 2252x op.stop_cb.reset();
127 2252x return dispatch_coro(ex, cont);
128 }
129
130 171x op.accepted_fd = accepted;
131 171x op.peer_storage = peer_storage;
132 171x op.peer_addrlen = peer_addrlen;
133 171x op.complete(0, 0);
134 171x op.object_ref_ = detail::object_ref(this);
135 171x this->svc_.post(&op);
136 171x return std::noop_coroutine();
137 }
138
139
6/16
✓ Branch 0 taken 572 times.
✓ Branch 1 taken 7294 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 572 times.
✓ Branch 4 taken 1228 times.
✓ Branch 5 taken 3839 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1228 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
12933x if (errno == EAGAIN || errno == EWOULDBLOCK)
140 {
141 11133x op.object_ref_ = detail::object_ref(this);
142 11133x this->svc_.work_started();
143
144 // Posted after the descriptor lock is released: the scheduler
145 // takes its own lock before descriptor locks.
146 11133x bool post_now = false;
147 {
148 11133x std::lock_guard lock(this->desc_state_.mutex);
149 11133x bool io_done = false;
150
3/8
✓ Branch 0 taken 7256 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 3839 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
11133x if (this->desc_state_.read_ready)
151 {
152 38x this->desc_state_.read_ready = false;
153 38x op.perform_io();
154
2/8
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
38x io_done = (op.errn != EAGAIN && op.errn != EWOULDBLOCK);
155
2/8
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
38x if (!io_done)
156 37x op.errn = 0;
157 38x }
158
159
5/16
✓ Branch 0 taken 7293 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 7293 times.
✓ Branch 4 taken 3839 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3839 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
11133x if (io_done || op.cancelled.load(std::memory_order_acquire))
160 {
161 1x post_now = true;
162 1x }
163 else
164 {
165 11132x this->desc_state_.read_op = &op;
166 // Select watches reads only for parked ops; see
167 // park_op.
168 if constexpr (Traits::needs_park_notification)
169
1/4
✓ Branch 0 taken 3839 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3839x this->svc_.scheduler().notify_reactor();
170 }
171 11133x }
172
3/8
✓ Branch 0 taken 7293 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3839 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
11133x if (post_now)
173 1x this->svc_.scheduler().post_counted(&op);
174 11133x return std::noop_coroutine();
175 }
176
177 1800x op.complete(errno, 0);
178 1800x op.object_ref_ = detail::object_ref(this);
179 1800x this->svc_.post(&op);
180 1800x return std::noop_coroutine();
181 15356x }
182
183 } // namespace boost::corosio::detail
184
185 #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
186