TLA Line data 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 : /* Parameterized reactor backend.
14 :
15 : Assembles all socket, service, acceptor, and op types for a given
16 : backend Traits type. Includes the accept() implementation (which
17 : needs all types to be complete) and the reactor_types<Traits>
18 : bundle used by backend.hpp.
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 Traits, class AccImplBase, class Endpoint>
35 : std::coroutine_handle<>
36 HIT 8530 : reactor_acceptor_final<Traits, AccImplBase, Endpoint>::accept(
37 : std::coroutine_handle<> h,
38 : capy::executor_ref ex,
39 : std::stop_token token,
40 : std::error_code* ec,
41 : io_object::implementation** impl_out)
42 : {
43 : using socket_final = stream_socket_t<Traits, Endpoint>;
44 :
45 8530 : auto& op = this->acc_;
46 8530 : op.reset();
47 8530 : op.h = h;
48 8530 : op.ex = ex;
49 8530 : op.ec_out = ec;
50 8530 : op.impl_out = impl_out;
51 8530 : op.fd = this->fd_;
52 8530 : op.start(token, this);
53 :
54 8530 : sockaddr_storage peer_storage{};
55 :
56 8530 : int accepted = Traits::accept_policy::do_accept(this->fd_, peer_storage);
57 :
58 8530 : if (accepted >= 0)
59 : {
60 : {
61 6 : std::lock_guard lock(this->desc_state_.mutex);
62 6 : this->desc_state_.read_ready = false;
63 6 : }
64 :
65 6 : if (this->svc_.scheduler().try_consume_inline_budget())
66 : {
67 MIS 0 : auto* socket_svc = this->svc_.stream_service();
68 0 : if (socket_svc)
69 : {
70 : auto& impl =
71 0 : static_cast<socket_final&>(*socket_svc->construct());
72 0 : impl.set_socket(accepted);
73 :
74 0 : impl.desc_state_.fd = accepted;
75 : {
76 0 : std::lock_guard lock(impl.desc_state_.mutex);
77 0 : impl.desc_state_.read_op = nullptr;
78 0 : impl.desc_state_.write_op = nullptr;
79 0 : impl.desc_state_.connect_op = nullptr;
80 0 : }
81 0 : socket_svc->scheduler().register_descriptor(
82 : accepted, &impl.desc_state_);
83 :
84 0 : impl.set_endpoints(
85 : this->local_endpoint_,
86 0 : from_sockaddr_as(
87 : peer_storage,
88 : static_cast<socklen_t>(sizeof(peer_storage)),
89 : Endpoint{}));
90 :
91 0 : *ec = {};
92 0 : if (impl_out)
93 0 : *impl_out = &impl;
94 : }
95 : else
96 : {
97 0 : ::close(accepted);
98 0 : *ec = make_err(ENOENT);
99 0 : if (impl_out)
100 0 : *impl_out = nullptr;
101 : }
102 0 : op.cont_op.cont.h = h;
103 0 : return dispatch_coro(ex, op.cont_op.cont);
104 : }
105 :
106 HIT 6 : op.accepted_fd = accepted;
107 6 : op.peer_storage = peer_storage;
108 6 : op.complete(0, 0);
109 6 : op.impl_ptr = this->shared_from_this();
110 6 : this->svc_.post(&op);
111 6 : return std::noop_coroutine();
112 : }
113 :
114 8524 : if (errno == EAGAIN || errno == EWOULDBLOCK)
115 : {
116 8524 : op.impl_ptr = this->shared_from_this();
117 8524 : this->svc_.work_started();
118 :
119 8524 : std::lock_guard lock(this->desc_state_.mutex);
120 8524 : bool io_done = false;
121 8524 : if (this->desc_state_.read_ready)
122 : {
123 MIS 0 : this->desc_state_.read_ready = false;
124 0 : op.perform_io();
125 0 : io_done = (op.errn != EAGAIN && op.errn != EWOULDBLOCK);
126 0 : if (!io_done)
127 0 : op.errn = 0;
128 : }
129 :
130 HIT 8524 : if (io_done || op.cancelled.load(std::memory_order_acquire))
131 : {
132 MIS 0 : this->svc_.post(&op);
133 0 : this->svc_.work_finished();
134 : }
135 : else
136 : {
137 HIT 8524 : this->desc_state_.read_op = &op;
138 : }
139 8524 : return std::noop_coroutine();
140 8524 : }
141 :
142 MIS 0 : op.complete(errno, 0);
143 0 : op.impl_ptr = this->shared_from_this();
144 0 : this->svc_.post(&op);
145 0 : return std::noop_coroutine();
146 : }
147 :
148 : // ============================================================
149 : // Type bundle for backend.hpp
150 : // ============================================================
151 :
152 : template<class Traits>
153 : struct reactor_types
154 : {
155 : using tcp_socket_type = stream_socket_t<Traits, endpoint>;
156 : using tcp_service_type = reactor_tcp_service_final<
157 : Traits, tcp_socket_type>;
158 :
159 : using udp_socket_type = dgram_socket_t<Traits, endpoint>;
160 : using udp_service_type = reactor_udp_service_final<
161 : Traits, udp_socket_type>;
162 :
163 : using tcp_acceptor_type = stream_acceptor_t<Traits, endpoint>;
164 : using tcp_acceptor_service_type = reactor_acceptor_service_final<
165 : Traits, tcp_acceptor_service, tcp_acceptor_type,
166 : tcp_service_type, endpoint>;
167 :
168 : using local_stream_socket_type = stream_socket_t<Traits, local_endpoint>;
169 : using local_stream_service_type = reactor_local_stream_service_final<
170 : Traits, local_stream_socket_type>;
171 :
172 : using local_datagram_socket_type = dgram_socket_t<Traits, local_endpoint>;
173 : using local_datagram_service_type = reactor_local_dgram_service_final<
174 : Traits, local_datagram_socket_type>;
175 :
176 : using local_stream_acceptor_type = stream_acceptor_t<Traits, local_endpoint>;
177 : using local_stream_acceptor_service_type = reactor_acceptor_service_final<
178 : Traits, local_stream_acceptor_service, local_stream_acceptor_type,
179 : local_stream_service_type, local_endpoint>;
180 : };
181 :
182 : } // namespace boost::corosio::detail
183 :
184 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_BACKEND_HPP
|