include/boost/corosio/native/native_local_datagram_socket.hpp

100.0% Lines (91 / 91) 100.0% Functions (46 / 46)
native_local_datagram_socket.hpp
f(x) Functions (46)
Function Calls Lines Blocks
boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::get_impl() :77 10x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::get_impl() :77 10x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_send_to_awaitable<boost::capy::const_buffer>::native_send_to_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::capy::const_buffer, boost::corosio::local_endpoint, int) :91 4x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_send_to_awaitable<boost::capy::const_buffer>::native_send_to_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::capy::const_buffer, boost::corosio::local_endpoint, int) :91 4x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_send_to_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :104 2x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_send_to_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :104 2x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_recv_from_awaitable<boost::capy::mutable_buffer>::native_recv_from_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::capy::mutable_buffer, boost::corosio::local_endpoint&, int) :122 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_recv_from_awaitable<boost::capy::mutable_buffer>::native_recv_from_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::capy::mutable_buffer, boost::corosio::local_endpoint&, int) :122 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_recv_from_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :135 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_recv_from_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :135 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::corosio::wait_type) :148 2x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::corosio::wait_type) :148 2x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :156 1x 100.0% 80.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :156 1x 100.0% 80.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::corosio::local_endpoint) :168 5x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_connect_awaitable::native_connect_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::corosio::local_endpoint) :168 5x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_connect_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :177 4x 100.0% 80.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_connect_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :177 4x 100.0% 80.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_send_awaitable<boost::capy::const_buffer>::native_send_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::capy::const_buffer, int) :192 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_send_awaitable<boost::capy::const_buffer>::native_send_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::capy::const_buffer, int) :192 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_send_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :203 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_send_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :203 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_recv_awaitable<boost::capy::mutable_buffer>::native_recv_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>&, boost::capy::mutable_buffer, int) :219 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_recv_awaitable<boost::capy::mutable_buffer>::native_recv_awaitable(boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>&, boost::capy::mutable_buffer, int) :219 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_recv_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :230 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_recv_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :230 1x 100.0% 75.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::native_local_datagram_socket(boost::capy::execution_context&) :243 15x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::native_local_datagram_socket(boost::capy::execution_context&) :243 15x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::send_to<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::local_endpoint, boost::corosio::message_flags) :280 4x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::send_to<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::local_endpoint, boost::corosio::message_flags) :280 4x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::send_to<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::local_endpoint) :294 4x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::send_to<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::local_endpoint) :294 4x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::recv_from<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::local_endpoint&, boost::corosio::message_flags) :305 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::recv_from<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::local_endpoint&, boost::corosio::message_flags) :305 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::recv_from<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::local_endpoint&) :320 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::recv_from<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::local_endpoint&) :320 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :332 5x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :332 5x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::send<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::message_flags) :346 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::send<boost::capy::const_buffer>(boost::capy::const_buffer const&, boost::corosio::message_flags) :346 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::send<boost::capy::const_buffer>(boost::capy::const_buffer const&) :356 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::send<boost::capy::const_buffer>(boost::capy::const_buffer const&) :356 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::recv<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::message_flags) :367 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::recv<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&, boost::corosio::message_flags) :367 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::recv<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :377 3x 100.0% 100.0% auto boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::recv<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :377 3x 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_DATAGRAM_SOCKET_HPP
12 #define BOOST_COROSIO_NATIVE_NATIVE_LOCAL_DATAGRAM_SOCKET_HPP
13
14 #include <boost/corosio/detail/platform.hpp>
15
16 #if BOOST_COROSIO_POSIX
17
18 #include <boost/corosio/local_datagram_socket.hpp>
19 #include <boost/corosio/backend.hpp>
20 #include <boost/corosio/detail/op_base.hpp>
21
22 #ifndef BOOST_COROSIO_MRDOCS
23 #if BOOST_COROSIO_HAS_EPOLL
24 #include <boost/corosio/native/detail/epoll/epoll_types.hpp>
25 #endif
26
27 #if BOOST_COROSIO_HAS_SELECT
28 #include <boost/corosio/native/detail/select/select_types.hpp>
29 #endif
30
31 #if BOOST_COROSIO_HAS_KQUEUE
32 #include <boost/corosio/native/detail/kqueue/kqueue_types.hpp>
33 #endif
34
35 #if BOOST_COROSIO_HAS_URING
36 #include <boost/corosio/native/detail/uring/uring_types.hpp>
37 #endif
38 #endif // !BOOST_COROSIO_MRDOCS
39
40 namespace boost::corosio {
41
42 /** An asynchronous Unix datagram socket with devirtualized I/O.
43
44 This class template inherits from @ref local_datagram_socket
45 and shadows the async operations (`send_to`, `recv_from`,
46 `connect`, `send`, `recv`) with versions that call the backend
47 implementation directly, allowing the compiler to inline
48 through the entire call chain.
49
50 Non-async operations (`open`, `close`, `cancel`, `bind`,
51 socket options) remain unchanged and dispatch through the
52 compiled library.
53
54 A `native_local_datagram_socket` IS-A `local_datagram_socket`
55 and can be passed to any function expecting
56 `local_datagram_socket&`, in which case virtual dispatch is
57 used transparently.
58
59 @tparam Backend A backend tag value (e.g., `epoll`) whose type
60 provides the concrete implementation types.
61
62 @par Thread Safety
63 Same as @ref local_datagram_socket.
64
65 @par Example
66 @par !example open_bind_recv
67
68 @see local_datagram_socket, epoll_t, iocp_t
69 */
70 template<auto Backend>
71 class native_local_datagram_socket : public local_datagram_socket
72 {
73 using backend_type = decltype(Backend);
74 using impl_type = typename backend_type::local_datagram_socket_type;
75 using service_type = typename backend_type::local_datagram_service_type;
76
77 20x impl_type& get_impl() noexcept
78 {
79 20x return *static_cast<impl_type*>(h_.get());
80 }
81
82 template<class ConstBufferSequence>
83 struct native_send_to_awaitable
84 : detail::bytes_op_base<native_send_to_awaitable<ConstBufferSequence>>
85 {
86 native_local_datagram_socket& self_;
87 ConstBufferSequence buffers_;
88 corosio::local_endpoint dest_;
89 int flags_;
90
91 8x native_send_to_awaitable(
92 native_local_datagram_socket& self,
93 ConstBufferSequence buffers,
94 corosio::local_endpoint dest,
95 int flags) noexcept
96 8x : self_(self)
97 8x , buffers_(std::move(buffers))
98 8x , dest_(dest)
99 8x , flags_(flags)
100 {
101 8x }
102
103 std::coroutine_handle<>
104 4x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
105 {
106 12x return self_.get_impl().send_to(
107 4x h, ex, buffers_, dest_, flags_, this->token_, &this->ec_,
108 8x &this->bytes_);
109 }
110 };
111
112 template<class MutableBufferSequence>
113 struct native_recv_from_awaitable
114 : detail::bytes_op_base<
115 native_recv_from_awaitable<MutableBufferSequence>>
116 {
117 native_local_datagram_socket& self_;
118 MutableBufferSequence buffers_;
119 corosio::local_endpoint& source_;
120 int flags_;
121
122 6x native_recv_from_awaitable(
123 native_local_datagram_socket& self,
124 MutableBufferSequence buffers,
125 corosio::local_endpoint& source,
126 int flags) noexcept
127 6x : self_(self)
128 6x , buffers_(std::move(buffers))
129 6x , source_(source)
130 6x , flags_(flags)
131 {
132 6x }
133
134 std::coroutine_handle<>
135 2x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
136 {
137 6x return self_.get_impl().recv_from(
138 2x h, ex, buffers_, &source_, flags_, this->token_, &this->ec_,
139 4x &this->bytes_);
140 }
141 };
142
143 struct native_wait_awaitable : detail::void_op_base<native_wait_awaitable>
144 {
145 native_local_datagram_socket& self_;
146 wait_type w_;
147
148 4x native_wait_awaitable(
149 native_local_datagram_socket& self, wait_type w) noexcept
150 4x : self_(self)
151 4x , w_(w)
152 {
153 4x }
154
155 std::coroutine_handle<>
156 2x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
157 {
158 2x return self_.get_impl().wait(h, ex, w_, this->token_, &this->ec_);
159 }
160 };
161
162 struct native_connect_awaitable
163 : detail::void_op_base<native_connect_awaitable>
164 {
165 native_local_datagram_socket& self_;
166 corosio::local_endpoint endpoint_;
167
168 10x native_connect_awaitable(
169 native_local_datagram_socket& self,
170 corosio::local_endpoint ep) noexcept
171 10x : self_(self)
172 10x , endpoint_(ep)
173 {
174 10x }
175
176 std::coroutine_handle<>
177 8x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
178 {
179 24x return self_.get_impl().connect(
180 24x h, ex, endpoint_, this->token_, &this->ec_);
181 }
182 };
183
184 template<class ConstBufferSequence>
185 struct native_send_awaitable
186 : detail::bytes_op_base<native_send_awaitable<ConstBufferSequence>>
187 {
188 native_local_datagram_socket& self_;
189 ConstBufferSequence buffers_;
190 int flags_;
191
192 6x native_send_awaitable(
193 native_local_datagram_socket& self,
194 ConstBufferSequence buffers,
195 int flags) noexcept
196 6x : self_(self)
197 6x , buffers_(std::move(buffers))
198 6x , flags_(flags)
199 {
200 6x }
201
202 std::coroutine_handle<>
203 2x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
204 {
205 6x return self_.get_impl().send(
206 2x h, ex, buffers_, flags_, this->token_, &this->ec_,
207 4x &this->bytes_);
208 }
209 };
210
211 template<class MutableBufferSequence>
212 struct native_recv_awaitable
213 : detail::bytes_op_base<native_recv_awaitable<MutableBufferSequence>>
214 {
215 native_local_datagram_socket& self_;
216 MutableBufferSequence buffers_;
217 int flags_;
218
219 6x native_recv_awaitable(
220 native_local_datagram_socket& self,
221 MutableBufferSequence buffers,
222 int flags) noexcept
223 6x : self_(self)
224 6x , buffers_(std::move(buffers))
225 6x , flags_(flags)
226 {
227 6x }
228
229 std::coroutine_handle<>
230 2x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
231 {
232 6x return self_.get_impl().recv(
233 2x h, ex, buffers_, flags_, this->token_, &this->ec_,
234 4x &this->bytes_);
235 }
236 };
237
238 public:
239 /** Construct a native socket from an execution context.
240
241 @param ctx The execution context that will own this socket.
242 */
243 30x explicit native_local_datagram_socket(capy::execution_context& ctx)
244 30x : local_datagram_socket(create_handle<service_type>(ctx))
245 {
246 30x }
247
248 /** Construct a native socket from an executor.
249
250 @param ex The executor whose context will own the socket.
251 */
252 template<class Ex>
253 requires(!std::same_as<
254 std::remove_cvref_t<Ex>,
255 native_local_datagram_socket>) &&
256 capy::Executor<Ex>
257 explicit native_local_datagram_socket(Ex const& ex)
258 : native_local_datagram_socket(ex.context())
259 {
260 }
261
262 /// Move construct.
263 native_local_datagram_socket(native_local_datagram_socket&&) noexcept =
264 default;
265
266 /// Move assign.
267 native_local_datagram_socket&
268 operator=(native_local_datagram_socket&&) noexcept = default;
269
270 native_local_datagram_socket(native_local_datagram_socket const&) = delete;
271 native_local_datagram_socket&
272 operator=(native_local_datagram_socket const&) = delete;
273
274 /** Send a datagram to the specified destination.
275
276 Calls the backend implementation directly, bypassing virtual
277 dispatch. Otherwise identical to @ref local_datagram_socket::send_to.
278 */
279 template<capy::ConstBufferSequence CB>
280 8x [[nodiscard]] auto send_to(
281 CB const& buffers,
282 corosio::local_endpoint dest,
283 corosio::message_flags flags)
284 {
285 8x native_send_to_awaitable<CB> aw(
286 *this, buffers, dest, static_cast<int>(flags));
287 8x if (!is_open())
288 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
289 8x return aw;
290 }
291
292 /// @overload
293 template<capy::ConstBufferSequence CB>
294 8x [[nodiscard]] auto send_to(CB const& buffers, corosio::local_endpoint dest)
295 {
296 8x return send_to(buffers, dest, corosio::message_flags::none);
297 }
298
299 /** Receive a datagram and capture the sender's endpoint.
300
301 Calls the backend implementation directly, bypassing virtual
302 dispatch. Otherwise identical to @ref local_datagram_socket::recv_from.
303 */
304 template<capy::MutableBufferSequence MB>
305 6x [[nodiscard]] auto recv_from(
306 MB const& buffers,
307 corosio::local_endpoint& source,
308 corosio::message_flags flags)
309 {
310 6x native_recv_from_awaitable<MB> aw(
311 *this, buffers, source, static_cast<int>(flags));
312 6x if (!is_open())
313 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
314 6x return aw;
315 }
316
317 /// @overload
318 template<capy::MutableBufferSequence MB>
319 [[nodiscard]] auto
320 6x recv_from(MB const& buffers, corosio::local_endpoint& source)
321 {
322 6x return recv_from(buffers, source, corosio::message_flags::none);
323 }
324
325 /** Asynchronously connect to set the default peer.
326
327 Calls the backend implementation directly, bypassing virtual
328 dispatch. Otherwise identical to @ref local_datagram_socket::connect.
329
330 If the socket is not already open, it is opened automatically.
331 */
332 10x [[nodiscard]] auto connect(corosio::local_endpoint ep)
333 {
334 10x native_connect_awaitable aw(*this, ep);
335 10x if (!is_open())
336 2x aw.ec_ = open();
337 10x return aw;
338 }
339
340 /** Send a datagram to the connected peer.
341
342 Calls the backend implementation directly, bypassing virtual
343 dispatch. Otherwise identical to @ref local_datagram_socket::send.
344 */
345 template<capy::ConstBufferSequence CB>
346 6x [[nodiscard]] auto send(CB const& buffers, corosio::message_flags flags)
347 {
348 6x native_send_awaitable<CB> aw(*this, buffers, static_cast<int>(flags));
349 6x if (!is_open())
350 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
351 6x return aw;
352 }
353
354 /// @overload
355 template<capy::ConstBufferSequence CB>
356 6x [[nodiscard]] auto send(CB const& buffers)
357 {
358 6x return send(buffers, corosio::message_flags::none);
359 }
360
361 /** Receive a datagram from the connected peer.
362
363 Calls the backend implementation directly, bypassing virtual
364 dispatch. Otherwise identical to @ref local_datagram_socket::recv.
365 */
366 template<capy::MutableBufferSequence MB>
367 6x [[nodiscard]] auto recv(MB const& buffers, corosio::message_flags flags)
368 {
369 6x native_recv_awaitable<MB> aw(*this, buffers, static_cast<int>(flags));
370 6x if (!is_open())
371 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
372 6x return aw;
373 }
374
375 /// @overload
376 template<capy::MutableBufferSequence MB>
377 6x [[nodiscard]] auto recv(MB const& buffers)
378 {
379 6x return recv(buffers, corosio::message_flags::none);
380 }
381
382 /** Asynchronously wait for the socket to be ready.
383
384 Calls the backend implementation directly, bypassing virtual
385 dispatch. Otherwise identical to @ref local_datagram_socket::wait.
386
387 @param w The wait direction (read, write, or error).
388
389 @return An awaitable yielding `io_result<>`.
390 */
391 4x [[nodiscard]] auto wait(wait_type w)
392 {
393 4x return native_wait_awaitable(*this, w);
394 }
395 };
396
397 } // namespace boost::corosio
398
399 #endif // BOOST_COROSIO_POSIX
400
401 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_DATAGRAM_SOCKET_HPP
402