]>
Commit | Line | Data |
---|---|---|
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 | ||
45 | namespace boost { | |
46 | namespace asio { | |
47 | namespace 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 | 58 | template <typename Executor = any_io_executor> |
7c673cae | 59 | class basic_descriptor |
92f5a8d4 | 60 | : public descriptor_base |
7c673cae FG |
61 | { |
62 | public: | |
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 | ||
665 | protected: | |
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 | |
682 | private: | |
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 |