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

86.8% Lines (66/76) 100.0% List of functions (4/4) 26.6% Branches (34/128)
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**) :37 14x 0.0% 0.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**) :37 5661x 100.0% 62.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**) :37 14x 52.6% 37.5% 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**) :37 2228x 86.8% 53.1% 62.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<class Derived, class Traits, class Service,
35 class SocketFinal, class AccImplBase, class Endpoint>
36 std::coroutine_handle<>
37 7917x reactor_acceptor_impl<Derived, Traits, Service, SocketFinal, AccImplBase, Endpoint>::accept(
38 std::coroutine_handle<> h,
39 capy::executor_ref ex,
40 std::stop_token token,
41 std::error_code* ec,
42 io_object::implementation** impl_out)
43 {
44 7917x auto& op = this->acc_;
45 7917x op.reset();
46 7917x op.h = h;
47 7917x op.ex = ex;
48 7917x op.ec_out = ec;
49 7917x op.impl_out = impl_out;
50 7917x op.fd = this->fd_;
51 7917x op.start(token, static_cast<Derived*>(this));
52
53 7917x sockaddr_storage peer_storage{};
54 7917x socklen_t peer_addrlen = 0;
55
56 7917x int accepted = Traits::accept_policy::do_accept(
57 7917x this->fd_, peer_storage, peer_addrlen);
58
59
4/8
✓ Branch 0 taken 5671 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2238 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
7917x if (accepted >= 0)
60 {
61 {
62 8x std::lock_guard lock(this->desc_state_.mutex);
63 8x this->desc_state_.read_ready = false;
64 8x }
65
66
4/8
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8x if (this->svc_.scheduler().try_consume_inline_budget())
67 {
68 2x auto* socket_svc = this->svc_.stream_service();
69
2/8
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2x if (socket_svc)
70 {
71 2x auto& impl =
72 2x static_cast<SocketFinal&>(*socket_svc->construct());
73 2x impl.set_socket(accepted);
74
75 2x impl.desc_state_.fd = accepted;
76 {
77 2x std::lock_guard lock(impl.desc_state_.mutex);
78 2x impl.desc_state_.read_op = nullptr;
79 2x impl.desc_state_.write_op = nullptr;
80 2x impl.desc_state_.connect_op = nullptr;
81 2x }
82 4x socket_svc->scheduler().register_descriptor(
83 2x accepted, &impl.desc_state_);
84
85 4x impl.set_endpoints(
86 2x this->local_endpoint_,
87 2x from_sockaddr_as(
88 2x peer_storage, peer_addrlen, Endpoint{}));
89
90 2x *ec = {};
91
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2x if (impl_out)
92 2x *impl_out = &impl;
93 2x }
94 else
95 {
96 ::close(accepted);
97 *ec = make_err(ENOENT);
98 if (impl_out)
99 *impl_out = nullptr;
100 }
101 2x op.cont_op.cont.h = h;
102 2x return dispatch_coro(ex, op.cont_op.cont);
103 }
104
105 6x op.accepted_fd = accepted;
106 6x op.peer_storage = peer_storage;
107 6x op.peer_addrlen = peer_addrlen;
108 6x op.complete(0, 0);
109
2/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6x op.impl_ptr = this->shared_from_this();
110 6x this->svc_.post(&op);
111 6x return std::noop_coroutine();
112 }
113
114
6/16
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5669 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2236 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 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.
7909x if (errno == EAGAIN || errno == EWOULDBLOCK)
115 {
116
2/8
✓ Branch 0 taken 5669 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2236 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
7905x op.impl_ptr = this->shared_from_this();
117 7905x this->svc_.work_started();
118
119 7905x std::lock_guard lock(this->desc_state_.mutex);
120 7905x bool io_done = false;
121
2/8
✓ Branch 0 taken 5669 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2236 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
7905x if (this->desc_state_.read_ready)
122 {
123 this->desc_state_.read_ready = false;
124 op.perform_io();
125 io_done = (op.errn != EAGAIN && op.errn != EWOULDBLOCK);
126 if (!io_done)
127 op.errn = 0;
128 }
129
130
6/16
✓ Branch 0 taken 5669 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 5668 times.
✓ Branch 4 taken 2236 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 2235 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.
7905x if (io_done || op.cancelled.load(std::memory_order_acquire))
131 {
132
2/8
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2x this->svc_.post(&op);
133 2x this->svc_.work_finished();
134 2x }
135 else
136 {
137 7903x this->desc_state_.read_op = &op;
138 }
139 7905x return std::noop_coroutine();
140 7905x }
141
142 4x op.complete(errno, 0);
143
2/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4x op.impl_ptr = this->shared_from_this();
144 4x this->svc_.post(&op);
145 4x return std::noop_coroutine();
146 7917x }
147
148 } // namespace boost::corosio::detail
149
150 #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
151