]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/posix/basic_descriptor.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / posix / basic_descriptor.hpp
CommitLineData
7c673cae
FG
1//
2// posix/basic_descriptor.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP
12#define BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
21 || defined(GENERATING_DOCUMENTATION)
22
20effc67 23#include <boost/asio/any_io_executor.hpp>
92f5a8d4
TL
24#include <boost/asio/async_result.hpp>
25#include <boost/asio/detail/handler_type_requirements.hpp>
26#include <boost/asio/detail/io_object_impl.hpp>
27#include <boost/asio/detail/non_const_lvalue.hpp>
7c673cae
FG
28#include <boost/asio/detail/throw_error.hpp>
29#include <boost/asio/error.hpp>
92f5a8d4 30#include <boost/asio/execution_context.hpp>
7c673cae
FG
31#include <boost/asio/posix/descriptor_base.hpp>
32
1e59de90
TL
33#if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
34# include <boost/asio/detail/io_uring_descriptor_service.hpp>
35#else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
36# include <boost/asio/detail/reactive_descriptor_service.hpp>
37#endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
38
92f5a8d4
TL
39#if defined(BOOST_ASIO_HAS_MOVE)
40# include <utility>
41#endif // defined(BOOST_ASIO_HAS_MOVE)
42
7c673cae
FG
43#include <boost/asio/detail/push_options.hpp>
44
45namespace boost {
46namespace asio {
47namespace posix {
48
49/// Provides POSIX descriptor functionality.
50/**
51 * The posix::basic_descriptor class template provides the ability to wrap a
52 * POSIX descriptor.
53 *
54 * @par Thread Safety
55 * @e Distinct @e objects: Safe.@n
56 * @e Shared @e objects: Unsafe.
57 */
20effc67 58template <typename Executor = any_io_executor>
7c673cae 59class basic_descriptor
92f5a8d4 60 : public descriptor_base
7c673cae
FG
61{
62public:
92f5a8d4
TL
63 /// The type of the executor associated with the object.
64 typedef Executor executor_type;
65
66 /// Rebinds the descriptor type to another executor.
67 template <typename Executor1>
68 struct rebind_executor
69 {
70 /// The descriptor type when rebound to the specified executor.
71 typedef basic_descriptor<Executor1> other;
72 };
73
7c673cae 74 /// The native representation of a descriptor.
92f5a8d4
TL
75#if defined(GENERATING_DOCUMENTATION)
76 typedef implementation_defined native_handle_type;
1e59de90
TL
77#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
78 typedef detail::io_uring_descriptor_service::native_handle_type
79 native_handle_type;
80#else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
92f5a8d4
TL
81 typedef detail::reactive_descriptor_service::native_handle_type
82 native_handle_type;
1e59de90 83#endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
7c673cae 84
92f5a8d4
TL
85 /// A descriptor is always the lowest layer.
86 typedef basic_descriptor lowest_layer_type;
7c673cae 87
92f5a8d4 88 /// Construct a descriptor without opening it.
7c673cae
FG
89 /**
90 * This constructor creates a descriptor without opening it.
91 *
92f5a8d4 92 * @param ex The I/O executor that the descriptor will use, by default, to
7c673cae
FG
93 * dispatch handlers for any asynchronous operations performed on the
94 * descriptor.
95 */
92f5a8d4 96 explicit basic_descriptor(const executor_type& ex)
1e59de90 97 : impl_(0, ex)
7c673cae
FG
98 {
99 }
100
92f5a8d4
TL
101 /// Construct a descriptor without opening it.
102 /**
103 * This constructor creates a descriptor without opening it.
104 *
105 * @param context An execution context which provides the I/O executor that
106 * the descriptor will use, by default, to dispatch handlers for any
107 * asynchronous operations performed on the descriptor.
108 */
109 template <typename ExecutionContext>
110 explicit basic_descriptor(ExecutionContext& context,
1e59de90
TL
111 typename constraint<
112 is_convertible<ExecutionContext&, execution_context&>::value,
113 defaulted_constraint
114 >::type = defaulted_constraint())
115 : impl_(0, 0, context)
92f5a8d4
TL
116 {
117 }
118
119 /// Construct a descriptor on an existing native descriptor.
7c673cae
FG
120 /**
121 * This constructor creates a descriptor object to hold an existing native
122 * descriptor.
123 *
92f5a8d4 124 * @param ex The I/O executor that the descriptor will use, by default, to
7c673cae
FG
125 * dispatch handlers for any asynchronous operations performed on the
126 * descriptor.
127 *
128 * @param native_descriptor A native descriptor.
129 *
130 * @throws boost::system::system_error Thrown on failure.
131 */
92f5a8d4 132 basic_descriptor(const executor_type& ex,
7c673cae 133 const native_handle_type& native_descriptor)
1e59de90 134 : impl_(0, ex)
92f5a8d4
TL
135 {
136 boost::system::error_code ec;
137 impl_.get_service().assign(impl_.get_implementation(),
138 native_descriptor, ec);
139 boost::asio::detail::throw_error(ec, "assign");
140 }
141
142 /// Construct a descriptor on an existing native descriptor.
143 /**
144 * This constructor creates a descriptor object to hold an existing native
145 * descriptor.
146 *
147 * @param context An execution context which provides the I/O executor that
148 * the descriptor will use, by default, to dispatch handlers for any
149 * asynchronous operations performed on the descriptor.
150 *
151 * @param native_descriptor A native descriptor.
152 *
153 * @throws boost::system::system_error Thrown on failure.
154 */
155 template <typename ExecutionContext>
156 basic_descriptor(ExecutionContext& context,
157 const native_handle_type& native_descriptor,
1e59de90 158 typename constraint<
92f5a8d4 159 is_convertible<ExecutionContext&, execution_context&>::value
1e59de90
TL
160 >::type = 0)
161 : impl_(0, 0, context)
7c673cae
FG
162 {
163 boost::system::error_code ec;
92f5a8d4 164 impl_.get_service().assign(impl_.get_implementation(),
7c673cae
FG
165 native_descriptor, ec);
166 boost::asio::detail::throw_error(ec, "assign");
167 }
168
169#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
92f5a8d4 170 /// Move-construct a descriptor from another.
7c673cae
FG
171 /**
172 * This constructor moves a descriptor from one object to another.
173 *
92f5a8d4 174 * @param other The other descriptor object from which the move will
7c673cae
FG
175 * occur.
176 *
177 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
178 * constructed using the @c basic_descriptor(const executor_type&)
179 * constructor.
7c673cae 180 */
f67539c2 181 basic_descriptor(basic_descriptor&& other) BOOST_ASIO_NOEXCEPT
92f5a8d4 182 : impl_(std::move(other.impl_))
7c673cae
FG
183 {
184 }
185
92f5a8d4 186 /// Move-assign a descriptor from another.
7c673cae
FG
187 /**
188 * This assignment operator moves a descriptor from one object to another.
189 *
92f5a8d4 190 * @param other The other descriptor object from which the move will
7c673cae
FG
191 * occur.
192 *
193 * @note Following the move, the moved-from object is in the same state as if
92f5a8d4
TL
194 * constructed using the @c basic_descriptor(const executor_type&)
195 * constructor.
7c673cae
FG
196 */
197 basic_descriptor& operator=(basic_descriptor&& other)
198 {
92f5a8d4 199 impl_ = std::move(other.impl_);
7c673cae
FG
200 return *this;
201 }
202#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
203
92f5a8d4
TL
204 /// Get the executor associated with the object.
205 executor_type get_executor() BOOST_ASIO_NOEXCEPT
206 {
207 return impl_.get_executor();
208 }
209
7c673cae
FG
210 /// Get a reference to the lowest layer.
211 /**
212 * This function returns a reference to the lowest layer in a stack of
92f5a8d4 213 * layers. Since a descriptor cannot contain any further layers, it
7c673cae
FG
214 * simply returns a reference to itself.
215 *
216 * @return A reference to the lowest layer in the stack of layers. Ownership
217 * is not transferred to the caller.
218 */
219 lowest_layer_type& lowest_layer()
220 {
221 return *this;
222 }
223
224 /// Get a const reference to the lowest layer.
225 /**
226 * This function returns a const reference to the lowest layer in a stack of
92f5a8d4 227 * layers. Since a descriptor cannot contain any further layers, it
7c673cae
FG
228 * simply returns a reference to itself.
229 *
230 * @return A const reference to the lowest layer in the stack of layers.
231 * Ownership is not transferred to the caller.
232 */
233 const lowest_layer_type& lowest_layer() const
234 {
235 return *this;
236 }
237
238 /// Assign an existing native descriptor to the descriptor.
239 /*
240 * This function opens the descriptor to hold an existing native descriptor.
241 *
242 * @param native_descriptor A native descriptor.
243 *
244 * @throws boost::system::system_error Thrown on failure.
245 */
246 void assign(const native_handle_type& native_descriptor)
247 {
248 boost::system::error_code ec;
92f5a8d4 249 impl_.get_service().assign(impl_.get_implementation(),
7c673cae
FG
250 native_descriptor, ec);
251 boost::asio::detail::throw_error(ec, "assign");
252 }
253
254 /// Assign an existing native descriptor to the descriptor.
255 /*
256 * This function opens the descriptor to hold an existing native descriptor.
257 *
258 * @param native_descriptor A native descriptor.
259 *
260 * @param ec Set to indicate what error occurred, if any.
261 */
b32b8144 262 BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor,
7c673cae
FG
263 boost::system::error_code& ec)
264 {
92f5a8d4
TL
265 impl_.get_service().assign(
266 impl_.get_implementation(), native_descriptor, ec);
b32b8144 267 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
268 }
269
270 /// Determine whether the descriptor is open.
271 bool is_open() const
272 {
92f5a8d4 273 return impl_.get_service().is_open(impl_.get_implementation());
7c673cae
FG
274 }
275
276 /// Close the descriptor.
277 /**
278 * This function is used to close the descriptor. Any asynchronous read or
279 * write operations will be cancelled immediately, and will complete with the
280 * boost::asio::error::operation_aborted error.
281 *
282 * @throws boost::system::system_error Thrown on failure. Note that, even if
283 * the function indicates an error, the underlying descriptor is closed.
284 */
285 void close()
286 {
287 boost::system::error_code ec;
92f5a8d4 288 impl_.get_service().close(impl_.get_implementation(), ec);
7c673cae
FG
289 boost::asio::detail::throw_error(ec, "close");
290 }
291
292 /// Close the descriptor.
293 /**
294 * This function is used to close the descriptor. Any asynchronous read or
295 * write operations will be cancelled immediately, and will complete with the
296 * boost::asio::error::operation_aborted error.
297 *
298 * @param ec Set to indicate what error occurred, if any. Note that, even if
299 * the function indicates an error, the underlying descriptor is closed.
300 */
b32b8144 301 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
7c673cae 302 {
92f5a8d4 303 impl_.get_service().close(impl_.get_implementation(), ec);
b32b8144 304 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
305 }
306
307 /// Get the native descriptor representation.
308 /**
309 * This function may be used to obtain the underlying representation of the
310 * descriptor. This is intended to allow access to native descriptor
311 * functionality that is not otherwise provided.
312 */
313 native_handle_type native_handle()
314 {
92f5a8d4 315 return impl_.get_service().native_handle(impl_.get_implementation());
7c673cae
FG
316 }
317
318 /// Release ownership of the native descriptor implementation.
319 /**
320 * This function may be used to obtain the underlying representation of the
321 * descriptor. After calling this function, @c is_open() returns false. The
322 * caller is responsible for closing the descriptor.
323 *
324 * All outstanding asynchronous read or write operations will finish
325 * immediately, and the handlers for cancelled operations will be passed the
326 * boost::asio::error::operation_aborted error.
327 */
328 native_handle_type release()
329 {
92f5a8d4 330 return impl_.get_service().release(impl_.get_implementation());
7c673cae
FG
331 }
332
333 /// Cancel all asynchronous operations associated with the descriptor.
334 /**
335 * This function causes all outstanding asynchronous read or write operations
336 * to finish immediately, and the handlers for cancelled operations will be
337 * passed the boost::asio::error::operation_aborted error.
338 *
339 * @throws boost::system::system_error Thrown on failure.
340 */
341 void cancel()
342 {
343 boost::system::error_code ec;
92f5a8d4 344 impl_.get_service().cancel(impl_.get_implementation(), ec);
7c673cae
FG
345 boost::asio::detail::throw_error(ec, "cancel");
346 }
347
348 /// Cancel all asynchronous operations associated with the descriptor.
349 /**
350 * This function causes all outstanding asynchronous read or write operations
351 * to finish immediately, and the handlers for cancelled operations will be
352 * passed the boost::asio::error::operation_aborted error.
353 *
354 * @param ec Set to indicate what error occurred, if any.
355 */
b32b8144 356 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
7c673cae 357 {
92f5a8d4 358 impl_.get_service().cancel(impl_.get_implementation(), ec);
b32b8144 359 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
360 }
361
362 /// Perform an IO control command on the descriptor.
363 /**
364 * This function is used to execute an IO control command on the descriptor.
365 *
366 * @param command The IO control command to be performed on the descriptor.
367 *
368 * @throws boost::system::system_error Thrown on failure.
369 *
370 * @sa IoControlCommand @n
371 * boost::asio::posix::descriptor_base::bytes_readable @n
372 * boost::asio::posix::descriptor_base::non_blocking_io
373 *
374 * @par Example
375 * Getting the number of bytes ready to read:
376 * @code
92f5a8d4 377 * boost::asio::posix::stream_descriptor descriptor(my_context);
7c673cae
FG
378 * ...
379 * boost::asio::posix::stream_descriptor::bytes_readable command;
380 * descriptor.io_control(command);
381 * std::size_t bytes_readable = command.get();
382 * @endcode
383 */
384 template <typename IoControlCommand>
385 void io_control(IoControlCommand& command)
386 {
387 boost::system::error_code ec;
92f5a8d4 388 impl_.get_service().io_control(impl_.get_implementation(), command, ec);
7c673cae
FG
389 boost::asio::detail::throw_error(ec, "io_control");
390 }
391
392 /// Perform an IO control command on the descriptor.
393 /**
394 * This function is used to execute an IO control command on the descriptor.
395 *
396 * @param command The IO control command to be performed on the descriptor.
397 *
398 * @param ec Set to indicate what error occurred, if any.
399 *
400 * @sa IoControlCommand @n
401 * boost::asio::posix::descriptor_base::bytes_readable @n
402 * boost::asio::posix::descriptor_base::non_blocking_io
403 *
404 * @par Example
405 * Getting the number of bytes ready to read:
406 * @code
92f5a8d4 407 * boost::asio::posix::stream_descriptor descriptor(my_context);
7c673cae
FG
408 * ...
409 * boost::asio::posix::stream_descriptor::bytes_readable command;
410 * boost::system::error_code ec;
411 * descriptor.io_control(command, ec);
412 * if (ec)
413 * {
414 * // An error occurred.
415 * }
416 * std::size_t bytes_readable = command.get();
417 * @endcode
418 */
419 template <typename IoControlCommand>
b32b8144 420 BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
7c673cae
FG
421 boost::system::error_code& ec)
422 {
92f5a8d4 423 impl_.get_service().io_control(impl_.get_implementation(), command, ec);
b32b8144 424 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
425 }
426
427 /// Gets the non-blocking mode of the descriptor.
428 /**
429 * @returns @c true if the descriptor's synchronous operations will fail with
430 * boost::asio::error::would_block if they are unable to perform the requested
431 * operation immediately. If @c false, synchronous operations will block
432 * until complete.
433 *
434 * @note The non-blocking mode has no effect on the behaviour of asynchronous
435 * operations. Asynchronous operations will never fail with the error
436 * boost::asio::error::would_block.
437 */
438 bool non_blocking() const
439 {
92f5a8d4 440 return impl_.get_service().non_blocking(impl_.get_implementation());
7c673cae
FG
441 }
442
443 /// Sets the non-blocking mode of the descriptor.
444 /**
445 * @param mode If @c true, the descriptor's synchronous operations will fail
446 * with boost::asio::error::would_block if they are unable to perform the
447 * requested operation immediately. If @c false, synchronous operations will
448 * block until complete.
449 *
450 * @throws boost::system::system_error Thrown on failure.
451 *
452 * @note The non-blocking mode has no effect on the behaviour of asynchronous
453 * operations. Asynchronous operations will never fail with the error
454 * boost::asio::error::would_block.
455 */
456 void non_blocking(bool mode)
457 {
458 boost::system::error_code ec;
92f5a8d4 459 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
7c673cae
FG
460 boost::asio::detail::throw_error(ec, "non_blocking");
461 }
462
463 /// Sets the non-blocking mode of the descriptor.
464 /**
465 * @param mode If @c true, the descriptor's synchronous operations will fail
466 * with boost::asio::error::would_block if they are unable to perform the
467 * requested operation immediately. If @c false, synchronous operations will
468 * block until complete.
469 *
470 * @param ec Set to indicate what error occurred, if any.
471 *
472 * @note The non-blocking mode has no effect on the behaviour of asynchronous
473 * operations. Asynchronous operations will never fail with the error
474 * boost::asio::error::would_block.
475 */
b32b8144 476 BOOST_ASIO_SYNC_OP_VOID non_blocking(
7c673cae
FG
477 bool mode, boost::system::error_code& ec)
478 {
92f5a8d4 479 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
b32b8144 480 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
7c673cae
FG
481 }
482
483 /// Gets the non-blocking mode of the native descriptor implementation.
484 /**
485 * This function is used to retrieve the non-blocking mode of the underlying
486 * native descriptor. This mode has no effect on the behaviour of the
487 * descriptor object's synchronous operations.
488 *
489 * @returns @c true if the underlying descriptor is in non-blocking mode and
490 * direct system calls may fail with boost::asio::error::would_block (or the
491 * equivalent system error).
492 *
493 * @note The current non-blocking mode is cached by the descriptor object.
494 * Consequently, the return value may be incorrect if the non-blocking mode
495 * was set directly on the native descriptor.
496 */
497 bool native_non_blocking() const
498 {
92f5a8d4
TL
499 return impl_.get_service().native_non_blocking(
500 impl_.get_implementation());
7c673cae
FG
501 }
502
503 /// Sets the non-blocking mode of the native descriptor implementation.
504 /**
505 * This function is used to modify the non-blocking mode of the underlying
506 * native descriptor. It has no effect on the behaviour of the descriptor
507 * object's synchronous operations.
508 *
509 * @param mode If @c true, the underlying descriptor is put into non-blocking
510 * mode and direct system calls may fail with boost::asio::error::would_block
511 * (or the equivalent system error).
512 *
513 * @throws boost::system::system_error Thrown on failure. If the @c mode is
514 * @c false, but the current value of @c non_blocking() is @c true, this
515 * function fails with boost::asio::error::invalid_argument, as the
516 * combination does not make sense.
517 */
518 void native_non_blocking(bool mode)
519 {
520 boost::system::error_code ec;
92f5a8d4
TL
521 impl_.get_service().native_non_blocking(
522 impl_.get_implementation(), mode, ec);
7c673cae
FG
523 boost::asio::detail::throw_error(ec, "native_non_blocking");
524 }
525
526 /// Sets the non-blocking mode of the native descriptor implementation.
527 /**
528 * This function is used to modify the non-blocking mode of the underlying
529 * native descriptor. It has no effect on the behaviour of the descriptor
530 * object's synchronous operations.
531 *
532 * @param mode If @c true, the underlying descriptor is put into non-blocking
533 * mode and direct system calls may fail with boost::asio::error::would_block
534 * (or the equivalent system error).
535 *
536 * @param ec Set to indicate what error occurred, if any. If the @c mode is
537 * @c false, but the current value of @c non_blocking() is @c true, this
538 * function fails with boost::asio::error::invalid_argument, as the
539 * combination does not make sense.
540 */
b32b8144 541 BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
7c673cae
FG
542 bool mode, boost::system::error_code& ec)
543 {
92f5a8d4
TL
544 impl_.get_service().native_non_blocking(
545 impl_.get_implementation(), mode, ec);
b32b8144
FG
546 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
547 }
548
549 /// Wait for the descriptor to become ready to read, ready to write, or to
550 /// have pending error conditions.
551 /**
552 * This function is used to perform a blocking wait for a descriptor to enter
553 * a ready to read, write or error condition state.
554 *
555 * @param w Specifies the desired descriptor state.
556 *
557 * @par Example
558 * Waiting for a descriptor to become readable.
559 * @code
92f5a8d4 560 * boost::asio::posix::stream_descriptor descriptor(my_context);
b32b8144
FG
561 * ...
562 * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read);
563 * @endcode
564 */
565 void wait(wait_type w)
566 {
567 boost::system::error_code ec;
92f5a8d4 568 impl_.get_service().wait(impl_.get_implementation(), w, ec);
b32b8144
FG
569 boost::asio::detail::throw_error(ec, "wait");
570 }
571
572 /// Wait for the descriptor to become ready to read, ready to write, or to
573 /// have pending error conditions.
574 /**
575 * This function is used to perform a blocking wait for a descriptor to enter
576 * a ready to read, write or error condition state.
577 *
578 * @param w Specifies the desired descriptor state.
579 *
580 * @param ec Set to indicate what error occurred, if any.
581 *
582 * @par Example
583 * Waiting for a descriptor to become readable.
584 * @code
92f5a8d4 585 * boost::asio::posix::stream_descriptor descriptor(my_context);
b32b8144
FG
586 * ...
587 * boost::system::error_code ec;
588 * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read, ec);
589 * @endcode
590 */
591 BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
592 {
92f5a8d4 593 impl_.get_service().wait(impl_.get_implementation(), w, ec);
b32b8144
FG
594 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
595 }
596
597 /// Asynchronously wait for the descriptor to become ready to read, ready to
598 /// write, or to have pending error conditions.
599 /**
600 * This function is used to perform an asynchronous wait for a descriptor to
1e59de90
TL
601 * enter a ready to read, write or error condition state. It is an initiating
602 * function for an @ref asynchronous_operation, and always returns
603 * immediately.
b32b8144
FG
604 *
605 * @param w Specifies the desired descriptor state.
606 *
1e59de90
TL
607 * @param token The @ref completion_token that will be used to produce a
608 * completion handler, which will be called when the wait completes.
609 * Potential completion tokens include @ref use_future, @ref use_awaitable,
610 * @ref yield_context, or a function object with the correct completion
611 * signature. The function signature of the completion handler must be:
b32b8144 612 * @code void handler(
1e59de90 613 * const boost::system::error_code& error // Result of operation.
b32b8144
FG
614 * ); @endcode
615 * Regardless of whether the asynchronous operation completes immediately or
1e59de90
TL
616 * not, the completion handler will not be invoked from within this function.
617 * On immediate completion, invocation of the handler will be performed in a
92f5a8d4 618 * manner equivalent to using boost::asio::post().
b32b8144 619 *
1e59de90
TL
620 * @par Completion Signature
621 * @code void(boost::system::error_code) @endcode
622 *
b32b8144
FG
623 * @par Example
624 * @code
625 * void wait_handler(const boost::system::error_code& error)
626 * {
627 * if (!error)
628 * {
629 * // Wait succeeded.
630 * }
631 * }
632 *
633 * ...
634 *
92f5a8d4 635 * boost::asio::posix::stream_descriptor descriptor(my_context);
b32b8144
FG
636 * ...
637 * descriptor.async_wait(
638 * boost::asio::posix::stream_descriptor::wait_read,
639 * wait_handler);
640 * @endcode
1e59de90
TL
641 *
642 * @par Per-Operation Cancellation
643 * This asynchronous operation supports cancellation for the following
644 * boost::asio::cancellation_type values:
645 *
646 * @li @c cancellation_type::terminal
647 *
648 * @li @c cancellation_type::partial
649 *
650 * @li @c cancellation_type::total
b32b8144 651 */
92f5a8d4
TL
652 template <
653 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1e59de90
TL
654 WaitToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
655 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitToken,
b32b8144 656 void (boost::system::error_code))
92f5a8d4 657 async_wait(wait_type w,
1e59de90 658 BOOST_ASIO_MOVE_ARG(WaitToken) token
92f5a8d4 659 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
b32b8144 660 {
1e59de90
TL
661 return async_initiate<WaitToken, void (boost::system::error_code)>(
662 initiate_async_wait(this), token, w);
7c673cae
FG
663 }
664
665protected:
666 /// Protected destructor to prevent deletion through this type.
92f5a8d4
TL
667 /**
668 * This function destroys the descriptor, cancelling any outstanding
669 * asynchronous wait operations associated with the descriptor as if by
670 * calling @c cancel.
671 */
7c673cae
FG
672 ~basic_descriptor()
673 {
674 }
92f5a8d4 675
1e59de90
TL
676#if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
677 detail::io_object_impl<detail::io_uring_descriptor_service, Executor> impl_;
678#else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
92f5a8d4 679 detail::io_object_impl<detail::reactive_descriptor_service, Executor> impl_;
1e59de90 680#endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
92f5a8d4
TL
681
682private:
683 // Disallow copying and assignment.
684 basic_descriptor(const basic_descriptor&) BOOST_ASIO_DELETED;
685 basic_descriptor& operator=(const basic_descriptor&) BOOST_ASIO_DELETED;
686
687 class initiate_async_wait
688 {
689 public:
690 typedef Executor executor_type;
691
692 explicit initiate_async_wait(basic_descriptor* self)
693 : self_(self)
694 {
695 }
696
697 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
698 {
699 return self_->get_executor();
700 }
701
702 template <typename WaitHandler>
703 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
704 {
705 // If you get an error on the following line it means that your handler
706 // does not meet the documented type requirements for a WaitHandler.
707 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
708
709 detail::non_const_lvalue<WaitHandler> handler2(handler);
710 self_->impl_.get_service().async_wait(
20effc67
TL
711 self_->impl_.get_implementation(), w,
712 handler2.value, self_->impl_.get_executor());
92f5a8d4
TL
713 }
714
715 private:
716 basic_descriptor* self_;
717 };
7c673cae
FG
718};
719
720} // namespace posix
721} // namespace asio
722} // namespace boost
723
724#include <boost/asio/detail/pop_options.hpp>
725
726#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
727 // || defined(GENERATING_DOCUMENTATION)
728
729#endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP