include/boost/corosio/native/native_local_stream_socket.hpp

100.0% Lines (46 / 46) 100.0% Functions (30 / 30)
native_local_stream_socket.hpp
f(x) Functions (30)
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(boost::capy::continuation&, 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(boost::capy::continuation&, 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(boost::capy::continuation&, 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(boost::capy::continuation&, 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(boost::capy::continuation&, 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(boost::capy::continuation&, 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) :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(boost::capy::continuation&, 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(boost::capy::continuation&, 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() :173 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket() :173 3x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::native_local_stream_socket(boost::capy::execution_context&) :180 18x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::native_local_stream_socket(boost::capy::execution_context&) :180 18x 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{}>&&) :200 4x 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{}>&&) :200 4x 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&) :222 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&) :222 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&) :237 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&) :237 4x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :256 6x 100.0% 100.0% boost::corosio::native_local_stream_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :256 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_acceptor_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 @ref local_stream_socket, @ref epoll_t, @ref 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(capy::continuation& cont, capy::executor_ref ex) const
97 {
98 18x return self_.get_impl().read_some(
99 18x cont, 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(capy::continuation& cont, capy::executor_ref ex) const
120 {
121 18x return self_.get_impl().write_some(
122 18x cont, 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(capy::continuation& cont, capy::executor_ref ex) const
140 {
141 8x return self_.get_impl().wait(
142 8x cont, 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(capy::continuation& cont, capy::executor_ref ex) const
162 {
163 30x return self_.get_impl().connect(
164 30x cont, ex, endpoint_, this->token_, &this->ec_);
165 }
166 };
167
168 // The peer a failed accept returns: it must not touch the
169 // acceptor's context, which a moved-from acceptor lacks.
170 template<auto>
171 friend class native_local_stream_acceptor;
172
173 6x native_local_stream_socket() noexcept = default;
174
175 public:
176 /** Construct a native socket from an execution context.
177
178 @param ctx The execution context that owns this socket.
179 */
180 36x explicit native_local_stream_socket(capy::execution_context& ctx)
181 36x : io_object(handle(ctx, ctx.use_service<service_type>()))
182 {
183 36x }
184
185 /** Construct a native socket from an executor.
186
187 @param ex The executor whose context owns the socket.
188 */
189 template<class Ex>
190 requires(!std::same_as<
191 std::remove_cvref_t<Ex>,
192 native_local_stream_socket>) &&
193 capy::Executor<Ex>
194 explicit native_local_stream_socket(Ex const& ex)
195 : native_local_stream_socket(ex.context())
196 {
197 }
198
199 /// Move construct.
200 8x native_local_stream_socket(native_local_stream_socket&&) noexcept = default;
201
202 /// Move assign.
203 native_local_stream_socket&
204 operator=(native_local_stream_socket&&) noexcept = default;
205
206 /// Copy construction is disabled; the handle is uniquely owned.
207 native_local_stream_socket(native_local_stream_socket const&) = delete;
208 /// Copy assignment is disabled; the handle is uniquely owned.
209 native_local_stream_socket&
210 operator=(native_local_stream_socket const&) = delete;
211
212 /** Asynchronously read data from the socket.
213
214 Calls the backend implementation directly, bypassing virtual
215 dispatch. Otherwise identical to @ref io_stream::read_some.
216
217 @param buffers The buffer sequence to read into.
218
219 @return An awaitable yielding `(error_code, std::size_t)`.
220 */
221 template<capy::MutableBufferSequence MB>
222 8x [[nodiscard]] auto read_some(MB const& buffers)
223 {
224 8x return native_read_awaitable<MB>(*this, buffers);
225 }
226
227 /** Asynchronously write data to the socket.
228
229 Calls the backend implementation directly, bypassing virtual
230 dispatch. Otherwise identical to @ref io_stream::write_some.
231
232 @param buffers The buffer sequence to write from.
233
234 @return An awaitable yielding `(error_code, std::size_t)`.
235 */
236 template<capy::ConstBufferSequence CB>
237 8x [[nodiscard]] auto write_some(CB const& buffers)
238 {
239 8x return native_write_awaitable<CB>(*this, buffers);
240 }
241
242 /** Asynchronously connect to a remote endpoint.
243
244 Calls the backend implementation directly, bypassing virtual
245 dispatch. Otherwise identical to @ref local_stream_socket::connect.
246
247 If the socket is not already open, it is opened automatically.
248
249 @param ep The local endpoint (path) to connect to.
250
251 @return An awaitable yielding `results<>`.
252
253 If the socket needs to be opened and the open fails, the
254 awaitable completes immediately with that error.
255 */
256 12x [[nodiscard]] auto connect(corosio::local_endpoint ep)
257 {
258 12x native_connect_awaitable aw(*this, ep);
259 12x if (!is_open())
260 10x aw.ec_ = open();
261 12x return aw;
262 }
263
264 /** Asynchronously wait for the socket to be ready.
265
266 Calls the backend implementation directly, bypassing virtual
267 dispatch. Otherwise identical to @ref local_stream_socket::wait.
268
269 @param w The wait direction (read, write, or error).
270
271 @return An awaitable yielding `results<>`.
272 */
273 6x [[nodiscard]] auto wait(wait_type w)
274 {
275 6x return native_wait_awaitable(*this, w);
276 }
277 };
278
279 } // namespace boost::corosio
280
281 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_STREAM_SOCKET_HPP
282