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() :75 13x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::get_impl() :75 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) :87 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) :87 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 :96 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 :96 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) :110 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) :110 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 :119 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 :119 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) :131 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) :131 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 :139 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 :139 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) :151 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) :151 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 :160 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 :160 5x 100.0% 80.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_local_stream_socket(boost::capy::execution_context&) :172 20x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket(boost::capy::execution_context&) :172 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{}>&&) :192 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{}>&&) :192 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&) :214 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&) :214 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&) :229 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&) :229 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :248 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :248 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 /** Reads and writes a Unix domain stream, calling the backend directly.
43
44 This class template inherits from @ref local_stream_socket. It
45 shadows the async operations (`read_some`, `write_some`, `connect`)
46 with versions that call the backend implementation directly. The
47 compiler can then inline through the entire 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 26x impl_type& get_impl() noexcept
76 {
77 26x return *static_cast<impl_type*>(h_.get());
78 }
79
80 template<class MutableBufferSequence>
81 struct native_read_awaitable
82 : detail::bytes_op_base<native_read_awaitable<MutableBufferSequence>>
83 {
84 native_local_stream_socket& self_;
85 MutableBufferSequence buffers_;
86
87 8x native_read_awaitable(
88 native_local_stream_socket& self,
89 MutableBufferSequence buffers) noexcept
90 8x : self_(self)
91 8x , buffers_(std::move(buffers))
92 {
93 8x }
94
95 std::coroutine_handle<>
96 6x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
97 {
98 18x return self_.get_impl().read_some(
99 18x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
100 }
101 };
102
103 template<class ConstBufferSequence>
104 struct native_write_awaitable
105 : detail::bytes_op_base<native_write_awaitable<ConstBufferSequence>>
106 {
107 native_local_stream_socket& self_;
108 ConstBufferSequence buffers_;
109
110 8x native_write_awaitable(
111 native_local_stream_socket& self,
112 ConstBufferSequence buffers) noexcept
113 8x : self_(self)
114 8x , buffers_(std::move(buffers))
115 {
116 8x }
117
118 std::coroutine_handle<>
119 6x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
120 {
121 18x return self_.get_impl().write_some(
122 18x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
123 }
124 };
125
126 struct native_wait_awaitable : detail::void_op_base<native_wait_awaitable>
127 {
128 native_local_stream_socket& self_;
129 wait_type w_;
130
131 6x native_wait_awaitable(
132 native_local_stream_socket& self, wait_type w) noexcept
133 6x : self_(self)
134 6x , w_(w)
135 {
136 6x }
137
138 std::coroutine_handle<>
139 4x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
140 {
141 4x return self_.get_impl().wait(h, ex, w_, this->token_, &this->ec_);
142 }
143 };
144
145 struct native_connect_awaitable
146 : detail::void_op_base<native_connect_awaitable>
147 {
148 native_local_stream_socket& self_;
149 corosio::local_endpoint endpoint_;
150
151 12x native_connect_awaitable(
152 native_local_stream_socket& self,
153 corosio::local_endpoint ep) noexcept
154 12x : self_(self)
155 12x , endpoint_(ep)
156 {
157 12x }
158
159 std::coroutine_handle<>
160 10x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
161 {
162 30x return self_.get_impl().connect(
163 30x h, ex, endpoint_, this->token_, &this->ec_);
164 }
165 };
166
167 public:
168 /** Construct a native socket from an execution context.
169
170 @param ctx The execution context that owns this socket.
171 */
172 40x explicit native_local_stream_socket(capy::execution_context& ctx)
173 40x : io_object(handle(ctx, ctx.use_service<service_type>()))
174 {
175 40x }
176
177 /** Construct a native socket from an executor.
178
179 @param ex The executor whose context owns the socket.
180 */
181 template<class Ex>
182 requires(!std::same_as<
183 std::remove_cvref_t<Ex>,
184 native_local_stream_socket>) &&
185 capy::Executor<Ex>
186 explicit native_local_stream_socket(Ex const& ex)
187 : native_local_stream_socket(ex.context())
188 {
189 }
190
191 /// Move construct.
192 6x native_local_stream_socket(native_local_stream_socket&&) noexcept = default;
193
194 /// Move assign.
195 native_local_stream_socket&
196 operator=(native_local_stream_socket&&) noexcept = default;
197
198 /// Copy construction is disabled; the handle is uniquely owned.
199 native_local_stream_socket(native_local_stream_socket const&) = delete;
200 /// Copy assignment is disabled; the handle is uniquely owned.
201 native_local_stream_socket&
202 operator=(native_local_stream_socket const&) = delete;
203
204 /** Asynchronously read data from the socket.
205
206 Calls the backend implementation directly, bypassing virtual
207 dispatch. Otherwise identical to @ref io_stream::read_some.
208
209 @param buffers The buffer sequence to read into.
210
211 @return An awaitable yielding `(error_code, std::size_t)`.
212 */
213 template<capy::MutableBufferSequence MB>
214 8x [[nodiscard]] auto read_some(MB const& buffers)
215 {
216 8x return native_read_awaitable<MB>(*this, buffers);
217 }
218
219 /** Asynchronously write data to the socket.
220
221 Calls the backend implementation directly, bypassing virtual
222 dispatch. Otherwise identical to @ref io_stream::write_some.
223
224 @param buffers The buffer sequence to write from.
225
226 @return An awaitable yielding `(error_code, std::size_t)`.
227 */
228 template<capy::ConstBufferSequence CB>
229 8x [[nodiscard]] auto write_some(CB const& buffers)
230 {
231 8x return native_write_awaitable<CB>(*this, buffers);
232 }
233
234 /** Asynchronously connect to a remote endpoint.
235
236 Calls the backend implementation directly, bypassing virtual
237 dispatch. Otherwise identical to @ref local_stream_socket::connect.
238
239 If the socket is not already open, it is opened automatically.
240
241 @param ep The local endpoint (path) to connect to.
242
243 @return An awaitable yielding `io_result<>`.
244
245 If the socket needs to be opened and the open fails, the
246 awaitable completes immediately with that error.
247 */
248 12x [[nodiscard]] auto connect(corosio::local_endpoint ep)
249 {
250 12x native_connect_awaitable aw(*this, ep);
251 12x if (!is_open())
252 10x aw.ec_ = open();
253 12x return aw;
254 }
255
256 /** Asynchronously wait for the socket to be ready.
257
258 Calls the backend implementation directly, bypassing virtual
259 dispatch. Otherwise identical to @ref local_stream_socket::wait.
260
261 @param w The wait direction (read, write, or error).
262
263 @return An awaitable yielding `io_result<>`.
264 */
265 6x [[nodiscard]] auto wait(wait_type w)
266 {
267 6x return native_wait_awaitable(*this, w);
268 }
269 };
270
271 } // namespace boost::corosio
272
273 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
274