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) :288 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) :288 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) :302 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) :302 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) :319 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) :319 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&) :334 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&) :334 3x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::epoll_t{}>::connect(boost::corosio::local_endpoint) :350 5x 100.0% 100.0% boost::corosio::native_local_datagram_socket<boost::corosio::select_t{}>::connect(boost::corosio::local_endpoint) :350 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) :369 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) :369 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&) :379 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&) :379 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) :395 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) :395 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&) :405 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&) :405 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 /** Sends and receives Unix domain datagrams, calling the backend directly.
43
44 This class template inherits from @ref local_datagram_socket. It
45 shadows the async operations (`send_to`, `recv_from`, `connect`,
46 `send`, `recv`) with versions that call the backend implementation
47 directly. The compiler can then inline through the entire call
48 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 owns this socket.
242 */
243 30x explicit native_local_datagram_socket(capy::execution_context& ctx)
244 30x : local_datagram_socket(handle(ctx, ctx.use_service<service_type>()))
245 {
246 30x }
247
248 /** Construct a native socket from an executor.
249
250 @param ex The executor whose context owns 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 /// Copy construction is disabled; the handle is uniquely owned.
271 native_local_datagram_socket(native_local_datagram_socket const&) = delete;
272 /// Copy assignment is disabled; the handle is uniquely owned.
273 native_local_datagram_socket&
274 operator=(native_local_datagram_socket const&) = delete;
275
276 /** Send a datagram to the specified destination.
277
278 Calls the backend implementation directly, bypassing virtual
279 dispatch. Otherwise identical to @ref local_datagram_socket::send_to.
280
281 @param buffers The buffer data to send.
282 @param dest The destination endpoint.
283 @param flags Message flags (e.g. `message_flags::do_not_route`).
284
285 @return An awaitable yielding the error code and the byte count sent.
286 */
287 template<capy::ConstBufferSequence CB>
288 8x [[nodiscard]] auto send_to(
289 CB const& buffers,
290 corosio::local_endpoint dest,
291 corosio::message_flags flags)
292 {
293 8x native_send_to_awaitable<CB> aw(
294 *this, buffers, dest, static_cast<int>(flags));
295 8x if (!is_open())
296 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
297 8x return aw;
298 }
299
300 /// @overload
301 template<capy::ConstBufferSequence CB>
302 8x [[nodiscard]] auto send_to(CB const& buffers, corosio::local_endpoint dest)
303 {
304 8x return send_to(buffers, dest, corosio::message_flags::none);
305 }
306
307 /** Receive a datagram and capture the sender's endpoint.
308
309 Calls the backend implementation directly, bypassing virtual
310 dispatch. Otherwise identical to @ref local_datagram_socket::recv_from.
311
312 @param buffers The buffers to receive into.
313 @param source Output endpoint for the sender's address.
314 @param flags Message flags (e.g. `message_flags::peek`).
315
316 @return An awaitable yielding the error code and the byte count received.
317 */
318 template<capy::MutableBufferSequence MB>
319 6x [[nodiscard]] auto recv_from(
320 MB const& buffers,
321 corosio::local_endpoint& source,
322 corosio::message_flags flags)
323 {
324 6x native_recv_from_awaitable<MB> aw(
325 *this, buffers, source, static_cast<int>(flags));
326 6x if (!is_open())
327 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
328 6x return aw;
329 }
330
331 /// @overload
332 template<capy::MutableBufferSequence MB>
333 [[nodiscard]] auto
334 6x recv_from(MB const& buffers, corosio::local_endpoint& source)
335 {
336 6x return recv_from(buffers, source, corosio::message_flags::none);
337 }
338
339 /** Asynchronously connect to set the default peer.
340
341 Calls the backend implementation directly, bypassing virtual
342 dispatch. Otherwise identical to @ref local_datagram_socket::connect.
343
344 If the socket is not already open, it is opened automatically.
345
346 @param ep The endpoint to set as the default destination.
347
348 @return An awaitable yielding the error code.
349 */
350 10x [[nodiscard]] auto connect(corosio::local_endpoint ep)
351 {
352 10x native_connect_awaitable aw(*this, ep);
353 10x if (!is_open())
354 2x aw.ec_ = open();
355 10x return aw;
356 }
357
358 /** Send a datagram to the connected peer.
359
360 Calls the backend implementation directly, bypassing virtual
361 dispatch. Otherwise identical to @ref local_datagram_socket::send.
362
363 @param buffers The buffer data to send.
364 @param flags Message flags (e.g. `message_flags::do_not_route`).
365
366 @return An awaitable yielding the error code and the byte count sent.
367 */
368 template<capy::ConstBufferSequence CB>
369 6x [[nodiscard]] auto send(CB const& buffers, corosio::message_flags flags)
370 {
371 6x native_send_awaitable<CB> aw(*this, buffers, static_cast<int>(flags));
372 6x if (!is_open())
373 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
374 6x return aw;
375 }
376
377 /// @overload
378 template<capy::ConstBufferSequence CB>
379 6x [[nodiscard]] auto send(CB const& buffers)
380 {
381 6x return send(buffers, corosio::message_flags::none);
382 }
383
384 /** Receive a datagram from the connected peer.
385
386 Calls the backend implementation directly, bypassing virtual
387 dispatch. Otherwise identical to @ref local_datagram_socket::recv.
388
389 @param buffers The buffers to receive into.
390 @param flags Message flags (e.g. `message_flags::peek`).
391
392 @return An awaitable yielding the error code and the byte count received.
393 */
394 template<capy::MutableBufferSequence MB>
395 6x [[nodiscard]] auto recv(MB const& buffers, corosio::message_flags flags)
396 {
397 6x native_recv_awaitable<MB> aw(*this, buffers, static_cast<int>(flags));
398 6x if (!is_open())
399 2x aw.ec_ = make_error_code(std::errc::bad_file_descriptor);
400 6x return aw;
401 }
402
403 /// @overload
404 template<capy::MutableBufferSequence MB>
405 6x [[nodiscard]] auto recv(MB const& buffers)
406 {
407 6x return recv(buffers, corosio::message_flags::none);
408 }
409
410 /** Asynchronously wait for the socket to be ready.
411
412 Calls the backend implementation directly, bypassing virtual
413 dispatch. Otherwise identical to @ref local_datagram_socket::wait.
414
415 @param w The wait direction (read, write, or error).
416
417 @return An awaitable yielding `io_result<>`.
418 */
419 4x [[nodiscard]] auto wait(wait_type w)
420 {
421 4x return native_wait_awaitable(*this, w);
422 }
423 };
424
425 } // namespace boost::corosio
426
427 #endif // BOOST_COROSIO_POSIX
428
429 #endif // BOOST_COROSIO_NATIVE_NATIVE_LOCAL_DATAGRAM_SOCKET_HPP
430