include/boost/corosio/native/native_local_stream_socket.hpp

100.0% Lines (44 / 44) 100.0% Functions (28 / 28)
native_local_stream_socket.hpp
f(x) Functions (28)
Function Calls Lines Blocks
boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::get_impl() :76 13x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::get_impl() :76 13x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>&, boost::capy::mutable_buffer) :88 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>&, boost::capy::mutable_buffer) :88 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :97 3x 100.0% 75.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :97 3x 100.0% 75.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>&, boost::capy::const_buffer) :111 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>&, boost::capy::const_buffer) :111 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :120 3x 100.0% 75.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :120 3x 100.0% 75.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>&, boost::corosio::wait_type) :132 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>&, boost::corosio::wait_type) :132 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :140 2x 100.0% 80.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :140 2x 100.0% 80.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>&, boost::corosio::local_endpoint) :152 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>&, boost::corosio::local_endpoint) :152 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :161 5x 100.0% 80.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_connect_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :161 5x 100.0% 80.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_local_stream_socket(boost::capy::execution_context&) :173 20x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket(boost::capy::execution_context&) :173 20x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_local_stream_socket(boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>&&) :193 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket(boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>&&) :193 3x 100.0% 100.0% auto boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :213 4x 100.0% 100.0% auto boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :213 4x 100.0% 100.0% auto boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :228 4x 100.0% 100.0% auto boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :228 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :247 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :247 6x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
12 #define BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
13
14 #include <boost/corosio/local_stream_socket.hpp>
15 #include <boost/corosio/backend.hpp>
16 #include <boost/corosio/detail/op_base.hpp>
17
18 #ifndef BOOST_COROSIO_MRDOCS
19 #if BOOST_COROSIO_HAS_EPOLL
20 #include <boost/corosio/native/detail/epoll/epoll_types.hpp>
21 #endif
22
23 #if BOOST_COROSIO_HAS_SELECT
24 #include <boost/corosio/native/detail/select/select_types.hpp>
25 #endif
26
27 #if BOOST_COROSIO_HAS_KQUEUE
28 #include <boost/corosio/native/detail/kqueue/kqueue_types.hpp>
29 #endif
30
31 #if BOOST_COROSIO_HAS_URING
32 #include <boost/corosio/native/detail/uring/uring_types.hpp>
33 #endif
34
35 #if BOOST_COROSIO_HAS_IOCP
36 #include <boost/corosio/native/detail/iocp/win_local_stream_service.hpp>
37 #endif
38 #endif // !BOOST_COROSIO_MRDOCS
39
40 namespace boost::corosio {
41
42 /** An asynchronous Unix stream socket with devirtualized I/O operations.
43
44 This class template inherits from @ref local_stream_socket and
45 shadows the async operations (`read_some`, `write_some`,
46 `connect`) with versions that call the backend implementation
47 directly, allowing the compiler to inline through the entire
48 call chain.
49
50 Non-async operations (`open`, `close`, `cancel`, socket options)
51 remain unchanged and dispatch through the compiled library.
52
53 A `native_local_stream_socket` IS-A `local_stream_socket` and
54 can be passed to any function expecting `local_stream_socket&`
55 or `io_stream&`, in which case virtual dispatch is used
56 transparently.
57
58 @tparam Backend A backend tag value (e.g., `epoll`) whose type
59 provides the concrete implementation types.
60
61 @par Thread Safety
62 Same as @ref local_stream_socket.
63
64 @par Example
65 @par !example connect
66
67 @see local_stream_socket, epoll_t, iocp_t
68 */
69 template<auto Backend>
70 class native_local_stream_socket : public local_stream_socket
71 {
72 using backend_type = decltype(Backend);
73 using impl_type = typename backend_type::local_stream_socket_type;
74 using service_type = typename backend_type::local_stream_service_type;
75
76 26x impl_type& get_impl() noexcept
77 {
78 26x return *static_cast<impl_type*>(h_.get());
79 }
80
81 template<class MutableBufferSequence>
82 struct native_read_awaitable
83 : detail::bytes_op_base<native_read_awaitable<MutableBufferSequence>>
84 {
85 native_local_stream_socket& self_;
86 MutableBufferSequence buffers_;
87
88 8x native_read_awaitable(
89 native_local_stream_socket& self,
90 MutableBufferSequence buffers) noexcept
91 8x : self_(self)
92 8x , buffers_(std::move(buffers))
93 {
94 8x }
95
96 std::coroutine_handle<>
97 6x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
98 {
99 18x return self_.get_impl().read_some(
100 18x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
101 }
102 };
103
104 template<class ConstBufferSequence>
105 struct native_write_awaitable
106 : detail::bytes_op_base<native_write_awaitable<ConstBufferSequence>>
107 {
108 native_local_stream_socket& self_;
109 ConstBufferSequence buffers_;
110
111 8x native_write_awaitable(
112 native_local_stream_socket& self,
113 ConstBufferSequence buffers) noexcept
114 8x : self_(self)
115 8x , buffers_(std::move(buffers))
116 {
117 8x }
118
119 std::coroutine_handle<>
120 6x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
121 {
122 18x return self_.get_impl().write_some(
123 18x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
124 }
125 };
126
127 struct native_wait_awaitable : detail::void_op_base<native_wait_awaitable>
128 {
129 native_local_stream_socket& self_;
130 wait_type w_;
131
132 6x native_wait_awaitable(
133 native_local_stream_socket& self, wait_type w) noexcept
134 6x : self_(self)
135 6x , w_(w)
136 {
137 6x }
138
139 std::coroutine_handle<>
140 4x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
141 {
142 4x return self_.get_impl().wait(h, ex, w_, this->token_, &this->ec_);
143 }
144 };
145
146 struct native_connect_awaitable
147 : detail::void_op_base<native_connect_awaitable>
148 {
149 native_local_stream_socket& self_;
150 corosio::local_endpoint endpoint_;
151
152 12x native_connect_awaitable(
153 native_local_stream_socket& self,
154 corosio::local_endpoint ep) noexcept
155 12x : self_(self)
156 12x , endpoint_(ep)
157 {
158 12x }
159
160 std::coroutine_handle<>
161 10x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
162 {
163 30x return self_.get_impl().connect(
164 30x h, ex, endpoint_, this->token_, &this->ec_);
165 }
166 };
167
168 public:
169 /** Construct a native socket from an execution context.
170
171 @param ctx The execution context that will own this socket.
172 */
173 40x explicit native_local_stream_socket(capy::execution_context& ctx)
174 40x : io_object(create_handle<service_type>(ctx))
175 {
176 40x }
177
178 /** Construct a native socket from an executor.
179
180 @param ex The executor whose context will own the socket.
181 */
182 template<class Ex>
183 requires(!std::same_as<
184 std::remove_cvref_t<Ex>,
185 native_local_stream_socket>) &&
186 capy::Executor<Ex>
187 explicit native_local_stream_socket(Ex const& ex)
188 : native_local_stream_socket(ex.context())
189 {
190 }
191
192 /// Move construct.
193 6x native_local_stream_socket(native_local_stream_socket&&) noexcept = default;
194
195 /// Move assign.
196 native_local_stream_socket&
197 operator=(native_local_stream_socket&&) noexcept = default;
198
199 native_local_stream_socket(native_local_stream_socket const&) = delete;
200 native_local_stream_socket&
201 operator=(native_local_stream_socket const&) = delete;
202
203 /** Asynchronously read data from the socket.
204
205 Calls the backend implementation directly, bypassing virtual
206 dispatch. Otherwise identical to @ref io_stream::read_some.
207
208 @param buffers The buffer sequence to read into.
209
210 @return An awaitable yielding `(error_code, std::size_t)`.
211 */
212 template<capy::MutableBufferSequence MB>
213 8x [[nodiscard]] auto read_some(MB const& buffers)
214 {
215 8x return native_read_awaitable<MB>(*this, buffers);
216 }
217
218 /** Asynchronously write data to the socket.
219
220 Calls the backend implementation directly, bypassing virtual
221 dispatch. Otherwise identical to @ref io_stream::write_some.
222
223 @param buffers The buffer sequence to write from.
224
225 @return An awaitable yielding `(error_code, std::size_t)`.
226 */
227 template<capy::ConstBufferSequence CB>
228 8x [[nodiscard]] auto write_some(CB const& buffers)
229 {
230 8x return native_write_awaitable<CB>(*this, buffers);
231 }
232
233 /** Asynchronously connect to a remote endpoint.
234
235 Calls the backend implementation directly, bypassing virtual
236 dispatch. Otherwise identical to @ref local_stream_socket::connect.
237
238 If the socket is not already open, it is opened automatically.
239
240 @param ep The local endpoint (path) to connect to.
241
242 @return An awaitable yielding `io_result<>`.
243
244 If the socket needs to be opened and the open fails, the
245 awaitable completes immediately with that error.
246 */
247 12x [[nodiscard]] auto connect(corosio::local_endpoint ep)
248 {
249 12x native_connect_awaitable aw(*this, ep);
250 12x if (!is_open())
251 10x aw.ec_ = open();
252 12x return aw;
253 }
254
255 /** Asynchronously wait for the socket to be ready.
256
257 Calls the backend implementation directly, bypassing virtual
258 dispatch. Otherwise identical to @ref local_stream_socket::wait.
259
260 @param w The wait direction (read, write, or error).
261
262 @return An awaitable yielding `io_result<>`.
263 */
264 6x [[nodiscard]] auto wait(wait_type w)
265 {
266 6x return native_wait_awaitable(*this, w);
267 }
268 };
269
270 } // namespace boost::corosio
271
272 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
273