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_STREAM_OPS_HPP
11 : #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_STREAM_OPS_HPP
12 :
13 : #include <boost/corosio/native/detail/reactor/reactor_op.hpp>
14 : #include <boost/corosio/native/detail/reactor/reactor_op_complete.hpp>
15 :
16 : namespace boost::corosio::detail {
17 :
18 : /* Parameterized stream op types for reactor backends.
19 :
20 : Given a Traits type (providing write_policy, accept_policy) and
21 : forward-declared Socket/Acceptor types, generates all the concrete
22 : op types needed for a stream socket. The cancel() and operator()()
23 : bodies reference Socket/Acceptor but are only instantiated when the
24 : vtable of a derived type is emitted -- at which point those types
25 : are complete.
26 :
27 : @tparam Traits Backend traits (epoll_traits, kqueue_traits, etc.)
28 : @tparam Socket The concrete stream socket type (forward-declared).
29 : @tparam Acceptor The concrete stream acceptor type (forward-declared).
30 : @tparam Endpoint The endpoint type (endpoint or local_endpoint).
31 : */
32 :
33 : template<class Traits, class Socket, class Acceptor, class Endpoint>
34 : struct reactor_stream_base_op : reactor_op<Socket, Acceptor>
35 : {
36 : void operator()() override;
37 : void cancel() noexcept override;
38 : };
39 :
40 : template<class Traits, class Socket, class Acceptor, class Endpoint>
41 : struct reactor_stream_connect_op final
42 : : reactor_connect_op<
43 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>,
44 : Endpoint>
45 : {
46 : void operator()() override;
47 : };
48 :
49 : template<class Traits, class Socket, class Acceptor, class Endpoint>
50 : struct reactor_stream_read_op final
51 : : reactor_read_op<
52 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>>
53 : {
54 : // A single buffer reads with recv(), which skips the VFS layer and
55 : // the iovec copy-in that readv() pays on every call.
56 HIT 1006 : void perform_io() noexcept override
57 : {
58 1006 : if (this->iovec_count != 1)
59 : return reactor_read_op<reactor_stream_base_op<
60 6 : Traits, Socket, Acceptor, Endpoint>>::perform_io();
61 :
62 : ssize_t n;
63 : do
64 : {
65 1000 : n = ::recv(
66 : this->fd, this->iovecs[0].iov_base, this->iovecs[0].iov_len, 0);
67 : }
68 1000 : while (n < 0 && errno == EINTR);
69 :
70 1000 : if (n >= 0)
71 888 : this->complete(0, static_cast<std::size_t>(n));
72 : else
73 112 : this->complete(errno, 0);
74 : }
75 : };
76 :
77 : template<class Traits, class Socket, class Acceptor, class Endpoint>
78 : struct reactor_stream_write_op final
79 : : reactor_write_op<
80 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>,
81 : typename Traits::write_policy>
82 : {};
83 :
84 : template<class Traits, class Socket, class Acceptor, class Endpoint>
85 : struct reactor_stream_accept_op final
86 : : reactor_accept_op<
87 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>,
88 : typename Traits::accept_policy>
89 : {
90 : void operator()() override;
91 : };
92 :
93 : template<class Traits, class Socket, class Acceptor, class Endpoint>
94 : struct reactor_stream_wait_op final
95 : : reactor_wait_op<
96 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>>
97 : {
98 : void operator()() override;
99 : };
100 :
101 : // --- Deferred implementations (instantiated when Socket/Acceptor are complete) ---
102 :
103 : template<class Traits, class Socket, class Acceptor, class Endpoint>
104 : void
105 86216 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>::operator()()
106 : {
107 86216 : complete_io_op(*this);
108 86216 : }
109 :
110 : template<class Traits, class Socket, class Acceptor, class Endpoint>
111 : void
112 938 : reactor_stream_base_op<Traits, Socket, Acceptor, Endpoint>::cancel() noexcept
113 : {
114 938 : if (this->socket_impl_)
115 578 : this->socket_impl_->cancel_single_op(*this);
116 360 : else if (this->acceptor_impl_)
117 360 : this->acceptor_impl_->cancel_single_op(*this);
118 : else
119 MIS 0 : this->request_cancel();
120 HIT 938 : }
121 :
122 : template<class Traits, class Socket, class Acceptor, class Endpoint>
123 : void
124 8416 : reactor_stream_connect_op<Traits, Socket, Acceptor, Endpoint>::operator()()
125 : {
126 8416 : complete_connect_op(*this);
127 8416 : }
128 :
129 : template<class Traits, class Socket, class Acceptor, class Endpoint>
130 : void
131 6093 : reactor_stream_accept_op<Traits, Socket, Acceptor, Endpoint>::operator()()
132 : {
133 6093 : complete_accept_op<Socket>(*this);
134 6093 : }
135 :
136 : template<class Traits, class Socket, class Acceptor, class Endpoint>
137 : void
138 122 : reactor_stream_wait_op<Traits, Socket, Acceptor, Endpoint>::operator()()
139 : {
140 122 : complete_wait_op(*this);
141 122 : }
142 :
143 : } // namespace boost::corosio::detail
144 :
145 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_STREAM_OPS_HPP
|