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

87.8% Lines (72/82) 100.0% List of functions (4/4) 40.3% Branches (58/144)
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(std::__1::coroutine_handle<void>, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 21x 75.6% 25.0% 42.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(std::__1::coroutine_handle<void>, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 4679x 64.6% 30.6% 60.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(std::__1::coroutine_handle<void>, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 20x 52.4% 19.4% 42.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(std::__1::coroutine_handle<void>, boost::capy::executor_ref, std::__1::stop_token, std::__1::error_code*, boost::corosio::io_object::implementation**) :49 1763x 81.7% 50.0% 60.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 6483x accept(
50 std::coroutine_handle<> h,
51 capy::executor_ref ex,
52 std::stop_token token,
53 std::error_code* ec,
54 io_object::implementation** impl_out)
55 {
56 6483x auto& op = this->acc_;
57 6483x op.reset();
58 6483x op.h = h;
59 6483x op.ex = ex;
60 6483x op.ec_out = ec;
61 6483x op.impl_out = impl_out;
62 6483x op.fd = this->fd_;
63 6483x op.start(token, static_cast<Derived*>(this));
64
65 6483x sockaddr_storage peer_storage{};
66 6483x socklen_t peer_addrlen = 0;
67
68 6483x int accepted =
69 6483x Traits::accept_policy::do_accept(this->fd_, peer_storage, peer_addrlen);
70
71
7/8
✓ Branch 0 taken 4618 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 1745 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 82 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
6483x if (accepted >= 0)
72 {
73 {
74 37x std::lock_guard lock(this->desc_state_.mutex);
75 37x this->desc_state_.read_ready = false;
76 37x }
77
78
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
37x if (this->svc_.scheduler().try_consume_inline_budget())
79 {
80 13x auto* socket_svc = this->svc_.stream_service();
81
3/8
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
13x if (socket_svc)
82 {
83 13x auto& impl =
84 13x static_cast<SocketFinal&>(*socket_svc->construct());
85 13x impl.set_socket(accepted);
86
87 13x impl.desc_state_.fd = accepted;
88 {
89 13x std::lock_guard lock(impl.desc_state_.mutex);
90 13x impl.desc_state_.read_op = nullptr;
91 13x impl.desc_state_.write_op = nullptr;
92 13x impl.desc_state_.connect_op = nullptr;
93 13x }
94 26x auto reg_ec = socket_svc->scheduler().register_descriptor(
95 13x accepted, &impl.desc_state_);
96
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
13x if (reg_ec)
97 {
98 // destroy() closes the fd the impl already owns.
99 1x socket_svc->destroy(&impl);
100 1x *ec = reg_ec;
101
1/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1x if (impl_out)
102 1x *impl_out = nullptr;
103 1x }
104 else
105 {
106 24x impl.set_endpoints(
107 12x this->local_endpoint_,
108 12x from_sockaddr_as(
109 12x peer_storage, peer_addrlen, Endpoint{}));
110
111 12x *ec = {};
112
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12x if (impl_out)
113 12x *impl_out = &impl;
114 }
115 13x }
116 else
117 {
118 ::close(accepted);
119 *ec = make_err(ENOENT);
120 if (impl_out)
121 *impl_out = nullptr;
122 }
123 13x op.cont.h = h;
124 13x return dispatch_coro(ex, op.cont);
125 }
126
127 24x op.accepted_fd = accepted;
128 24x op.peer_storage = peer_storage;
129 24x op.peer_addrlen = peer_addrlen;
130 24x op.complete(0, 0);
131
2/8
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24x op.impl_ptr = this->shared_from_this();
132 24x this->svc_.post(&op);
133 24x return std::noop_coroutine();
134 }
135
136
10/16
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4610 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1743 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 77 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6446x if (errno == EAGAIN || errno == EWOULDBLOCK)
137 {
138
4/8
✓ Branch 0 taken 4610 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1743 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 77 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
6431x op.impl_ptr = this->shared_from_this();
139 6431x this->svc_.work_started();
140
141 6431x std::lock_guard lock(this->desc_state_.mutex);
142 6431x bool io_done = false;
143
4/8
✓ Branch 0 taken 4610 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1743 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 77 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
6431x if (this->desc_state_.read_ready)
144 {
145 this->desc_state_.read_ready = false;
146 op.perform_io();
147 io_done = (op.errn != EAGAIN && op.errn != EWOULDBLOCK);
148 if (!io_done)
149 op.errn = 0;
150 }
151
152
10/16
✓ Branch 0 taken 4610 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4605 times.
✓ Branch 4 taken 1743 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 1738 times.
✓ Branch 8 taken 77 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 77 times.
✓ Branch 12 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 time.
6431x if (io_done || op.cancelled.load(std::memory_order_acquire))
153 {
154
2/8
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
10x this->svc_.post(&op);
155 10x this->svc_.work_finished();
156 10x }
157 else
158 {
159 6421x this->desc_state_.read_op = &op;
160 }
161 6431x return std::noop_coroutine();
162 6431x }
163
164 15x op.complete(errno, 0);
165
3/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15x op.impl_ptr = this->shared_from_this();
166 15x this->svc_.post(&op);
167 15x return std::noop_coroutine();
168 6483x }
169
170 } // namespace boost::corosio::detail
171
172 #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
173