include/boost/corosio/native/native_local_stream_socket.hpp

100.0% Lines (72/0/72) 100.0% List of functions (44/0/44)
native_local_stream_socket.hpp
f(x) Functions (44)
Function Calls Lines Blocks
boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::get_impl() :75 17x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::get_impl() :75 17x 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) :89 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) :89 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_ready() const :97 4x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_ready() const :97 4x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_resume() const :104 4x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_resume() const :104 4x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :111 4x 100.0% 77.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :111 4x 100.0% 77.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) :129 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) :129 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_ready() const :137 4x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_ready() const :137 4x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_resume() const :144 4x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_resume() const :144 4x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :151 4x 100.0% 77.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :151 4x 100.0% 77.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) :167 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) :167 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_ready() const :174 3x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_ready() const :174 3x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_resume() const :181 3x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_resume() const :181 3x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :188 3x 100.0% 82.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_wait_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :188 3x 100.0% 82.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) :203 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) :203 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_ready() const :211 6x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_ready() const :211 6x 100.0% 88.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_resume() const :218 6x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_resume() const :218 6x 100.0% 86.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :225 6x 100.0% 82.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_connect_awaitable::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :225 6x 100.0% 82.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_local_stream_socket(boost::capy::execution_context&) :239 20x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket(boost::capy::execution_context&) :239 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{}>&&) :259 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{}>&&) :259 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&) :279 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&) :279 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&) :294 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&) :294 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :313 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :313 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
17 #ifndef BOOST_COROSIO_MRDOCS
18 #if BOOST_COROSIO_HAS_EPOLL
19 #include <boost/corosio/native/detail/epoll/epoll_types.hpp>
20 #endif
21
22 #if BOOST_COROSIO_HAS_SELECT
23 #include <boost/corosio/native/detail/select/select_types.hpp>
24 #endif
25
26 #if BOOST_COROSIO_HAS_KQUEUE
27 #include <boost/corosio/native/detail/kqueue/kqueue_types.hpp>
28 #endif
29
30 #if BOOST_COROSIO_HAS_URING
31 #include <boost/corosio/native/detail/uring/uring_types.hpp>
32 #endif
33
34 #if BOOST_COROSIO_HAS_IOCP
35 #include <boost/corosio/native/detail/iocp/win_local_stream_service.hpp>
36 #endif
37 #endif // !BOOST_COROSIO_MRDOCS
38
39 namespace boost::corosio {
40
41 /** An asynchronous Unix stream socket with devirtualized I/O operations.
42
43 This class template inherits from @ref local_stream_socket and
44 shadows the async operations (`read_some`, `write_some`,
45 `connect`) with versions that call the backend implementation
46 directly, allowing the compiler to inline through the entire
47 call chain.
48
49 Non-async operations (`open`, `close`, `cancel`, socket options)
50 remain unchanged and dispatch through the compiled library.
51
52 A `native_local_stream_socket` IS-A `local_stream_socket` and
53 can be passed to any function expecting `local_stream_socket&`
54 or `io_stream&`, in which case virtual dispatch is used
55 transparently.
56
57 @tparam Backend A backend tag value (e.g., `epoll`) whose type
58 provides the concrete implementation types.
59
60 @par Thread Safety
61 Same as @ref local_stream_socket.
62
63 @par Example
64 @par !example connect
65
66 @see local_stream_socket, epoll_t, iocp_t
67 */
68 template<auto Backend>
69 class native_local_stream_socket : public local_stream_socket
70 {
71 using backend_type = decltype(Backend);
72 using impl_type = typename backend_type::local_stream_socket_type;
73 using service_type = typename backend_type::local_stream_service_type;
74
75 34x impl_type& get_impl() noexcept
76 {
77 34x return *static_cast<impl_type*>(h_.get());
78 }
79
80 template<class MutableBufferSequence>
81 struct native_read_awaitable
82 {
83 native_local_stream_socket& self_;
84 MutableBufferSequence buffers_;
85 std::stop_token token_;
86 mutable std::error_code ec_;
87 mutable std::size_t bytes_transferred_ = 0;
88
89 8x native_read_awaitable(
90 native_local_stream_socket& self,
91 MutableBufferSequence buffers) noexcept
92 8x : self_(self)
93 8x , buffers_(std::move(buffers))
94 {
95 8x }
96
97 8x bool await_ready() const noexcept
98 {
99 // A pre-set ec_ means the initiator failed before
100 // dispatch (e.g. a closed object).
101 8x return static_cast<bool>(ec_) || token_.stop_requested();
102 }
103
104 8x [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
105 {
106 8x if (token_.stop_requested())
107 2x return {make_error_code(std::errc::operation_canceled), 0};
108 6x return {ec_, bytes_transferred_};
109 }
110
111 8x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
112 -> std::coroutine_handle<>
113 {
114 8x token_ = env->stop_token;
115 24x return self_.get_impl().read_some(
116 24x h, env->executor, buffers_, token_, &ec_, &bytes_transferred_);
117 }
118 };
119
120 template<class ConstBufferSequence>
121 struct native_write_awaitable
122 {
123 native_local_stream_socket& self_;
124 ConstBufferSequence buffers_;
125 std::stop_token token_;
126 mutable std::error_code ec_;
127 mutable std::size_t bytes_transferred_ = 0;
128
129 8x native_write_awaitable(
130 native_local_stream_socket& self,
131 ConstBufferSequence buffers) noexcept
132 8x : self_(self)
133 8x , buffers_(std::move(buffers))
134 {
135 8x }
136
137 8x bool await_ready() const noexcept
138 {
139 // A pre-set ec_ means the initiator failed before
140 // dispatch (e.g. a closed object).
141 8x return static_cast<bool>(ec_) || token_.stop_requested();
142 }
143
144 8x [[nodiscard]] capy::io_result<std::size_t> await_resume() const noexcept
145 {
146 8x if (token_.stop_requested())
147 2x return {make_error_code(std::errc::operation_canceled), 0};
148 6x return {ec_, bytes_transferred_};
149 }
150
151 8x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
152 -> std::coroutine_handle<>
153 {
154 8x token_ = env->stop_token;
155 24x return self_.get_impl().write_some(
156 24x h, env->executor, buffers_, token_, &ec_, &bytes_transferred_);
157 }
158 };
159
160 struct native_wait_awaitable
161 {
162 native_local_stream_socket& self_;
163 wait_type w_;
164 std::stop_token token_;
165 mutable std::error_code ec_;
166
167 6x native_wait_awaitable(
168 native_local_stream_socket& self, wait_type w) noexcept
169 6x : self_(self)
170 6x , w_(w)
171 {
172 6x }
173
174 6x bool await_ready() const noexcept
175 {
176 // A pre-set ec_ means the initiator failed before
177 // dispatch (e.g. auto-open).
178 6x return static_cast<bool>(ec_) || token_.stop_requested();
179 }
180
181 6x [[nodiscard]] capy::io_result<> await_resume() const noexcept
182 {
183 6x if (token_.stop_requested())
184 2x return {make_error_code(std::errc::operation_canceled)};
185 4x return {ec_};
186 }
187
188 6x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
189 -> std::coroutine_handle<>
190 {
191 6x token_ = env->stop_token;
192 6x return self_.get_impl().wait(h, env->executor, w_, token_, &ec_);
193 }
194 };
195
196 struct native_connect_awaitable
197 {
198 native_local_stream_socket& self_;
199 corosio::local_endpoint endpoint_;
200 std::stop_token token_;
201 mutable std::error_code ec_;
202
203 12x native_connect_awaitable(
204 native_local_stream_socket& self,
205 corosio::local_endpoint ep) noexcept
206 12x : self_(self)
207 12x , endpoint_(ep)
208 {
209 12x }
210
211 12x bool await_ready() const noexcept
212 {
213 // A pre-set ec_ means the initiator failed before
214 // dispatch (e.g. a closed object).
215 12x return static_cast<bool>(ec_) || token_.stop_requested();
216 }
217
218 12x [[nodiscard]] capy::io_result<> await_resume() const noexcept
219 {
220 12x if (token_.stop_requested())
221 2x return {make_error_code(std::errc::operation_canceled)};
222 10x return {ec_};
223 }
224
225 12x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
226 -> std::coroutine_handle<>
227 {
228 12x token_ = env->stop_token;
229 36x return self_.get_impl().connect(
230 36x h, env->executor, endpoint_, token_, &ec_);
231 }
232 };
233
234 public:
235 /** Construct a native socket from an execution context.
236
237 @param ctx The execution context that will own this socket.
238 */
239 40x explicit native_local_stream_socket(capy::execution_context& ctx)
240 40x : io_object(create_handle<service_type>(ctx))
241 {
242 40x }
243
244 /** Construct a native socket from an executor.
245
246 @param ex The executor whose context will own the socket.
247 */
248 template<class Ex>
249 requires(!std::same_as<
250 std::remove_cvref_t<Ex>,
251 native_local_stream_socket>) &&
252 capy::Executor<Ex>
253 explicit native_local_stream_socket(Ex const& ex)
254 : native_local_stream_socket(ex.context())
255 {
256 }
257
258 /// Move construct.
259 6x native_local_stream_socket(native_local_stream_socket&&) noexcept = default;
260
261 /// Move assign.
262 native_local_stream_socket&
263 operator=(native_local_stream_socket&&) noexcept = default;
264
265 native_local_stream_socket(native_local_stream_socket const&) = delete;
266 native_local_stream_socket&
267 operator=(native_local_stream_socket const&) = delete;
268
269 /** Asynchronously read data from the socket.
270
271 Calls the backend implementation directly, bypassing virtual
272 dispatch. Otherwise identical to @ref io_stream::read_some.
273
274 @param buffers The buffer sequence to read into.
275
276 @return An awaitable yielding `(error_code, std::size_t)`.
277 */
278 template<capy::MutableBufferSequence MB>
279 8x [[nodiscard]] auto read_some(MB const& buffers)
280 {
281 8x return native_read_awaitable<MB>(*this, buffers);
282 }
283
284 /** Asynchronously write data to the socket.
285
286 Calls the backend implementation directly, bypassing virtual
287 dispatch. Otherwise identical to @ref io_stream::write_some.
288
289 @param buffers The buffer sequence to write from.
290
291 @return An awaitable yielding `(error_code, std::size_t)`.
292 */
293 template<capy::ConstBufferSequence CB>
294 8x [[nodiscard]] auto write_some(CB const& buffers)
295 {
296 8x return native_write_awaitable<CB>(*this, buffers);
297 }
298
299 /** Asynchronously connect to a remote endpoint.
300
301 Calls the backend implementation directly, bypassing virtual
302 dispatch. Otherwise identical to @ref local_stream_socket::connect.
303
304 If the socket is not already open, it is opened automatically.
305
306 @param ep The local endpoint (path) to connect to.
307
308 @return An awaitable yielding `io_result<>`.
309
310 If the socket needs to be opened and the open fails, the
311 awaitable completes immediately with that error.
312 */
313 12x [[nodiscard]] auto connect(corosio::local_endpoint ep)
314 {
315 12x native_connect_awaitable aw(*this, ep);
316 12x if (!is_open())
317 10x aw.ec_ = open();
318 12x return aw;
319 }
320
321 /** Asynchronously wait for the socket to be ready.
322
323 Calls the backend implementation directly, bypassing virtual
324 dispatch. Otherwise identical to @ref local_stream_socket::wait.
325
326 @param w The wait direction (read, write, or error).
327
328 @return An awaitable yielding `io_result<>`.
329 */
330 6x [[nodiscard]] auto wait(wait_type w)
331 {
332 6x return native_wait_awaitable(*this, w);
333 }
334 };
335
336 } // namespace boost::corosio
337
338 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
339