]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/posix/basic_descriptor.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / posix / basic_descriptor.hpp
1 //
2 // posix/basic_descriptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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_ENABLE_OLD_SERVICES)
21
22 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
23 || defined(GENERATING_DOCUMENTATION)
24
25 #include <boost/asio/basic_io_object.hpp>
26 #include <boost/asio/detail/throw_error.hpp>
27 #include <boost/asio/error.hpp>
28 #include <boost/asio/posix/descriptor_base.hpp>
29
30 #include <boost/asio/detail/push_options.hpp>
31
32 namespace boost {
33 namespace asio {
34 namespace posix {
35
36 /// Provides POSIX descriptor functionality.
37 /**
38 * The posix::basic_descriptor class template provides the ability to wrap a
39 * POSIX descriptor.
40 *
41 * @par Thread Safety
42 * @e Distinct @e objects: Safe.@n
43 * @e Shared @e objects: Unsafe.
44 */
45 template <typename DescriptorService>
46 class basic_descriptor
47 : public basic_io_object<DescriptorService>,
48 public descriptor_base
49 {
50 public:
51 /// The native representation of a descriptor.
52 typedef typename DescriptorService::native_handle_type native_handle_type;
53
54 /// A basic_descriptor is always the lowest layer.
55 typedef basic_descriptor<DescriptorService> lowest_layer_type;
56
57 /// Construct a basic_descriptor without opening it.
58 /**
59 * This constructor creates a descriptor without opening it.
60 *
61 * @param io_context The io_context object that the descriptor will use to
62 * dispatch handlers for any asynchronous operations performed on the
63 * descriptor.
64 */
65 explicit basic_descriptor(boost::asio::io_context& io_context)
66 : basic_io_object<DescriptorService>(io_context)
67 {
68 }
69
70 /// Construct a basic_descriptor on an existing native descriptor.
71 /**
72 * This constructor creates a descriptor object to hold an existing native
73 * descriptor.
74 *
75 * @param io_context The io_context object that the descriptor will use to
76 * dispatch handlers for any asynchronous operations performed on the
77 * descriptor.
78 *
79 * @param native_descriptor A native descriptor.
80 *
81 * @throws boost::system::system_error Thrown on failure.
82 */
83 basic_descriptor(boost::asio::io_context& io_context,
84 const native_handle_type& native_descriptor)
85 : basic_io_object<DescriptorService>(io_context)
86 {
87 boost::system::error_code ec;
88 this->get_service().assign(this->get_implementation(),
89 native_descriptor, ec);
90 boost::asio::detail::throw_error(ec, "assign");
91 }
92
93 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
94 /// Move-construct a basic_descriptor from another.
95 /**
96 * This constructor moves a descriptor from one object to another.
97 *
98 * @param other The other basic_descriptor object from which the move will
99 * occur.
100 *
101 * @note Following the move, the moved-from object is in the same state as if
102 * constructed using the @c basic_descriptor(io_context&) constructor.
103 */
104 basic_descriptor(basic_descriptor&& other)
105 : basic_io_object<DescriptorService>(
106 BOOST_ASIO_MOVE_CAST(basic_descriptor)(other))
107 {
108 }
109
110 /// Move-assign a basic_descriptor from another.
111 /**
112 * This assignment operator moves a descriptor from one object to another.
113 *
114 * @param other The other basic_descriptor object from which the move will
115 * occur.
116 *
117 * @note Following the move, the moved-from object is in the same state as if
118 * constructed using the @c basic_descriptor(io_context&) constructor.
119 */
120 basic_descriptor& operator=(basic_descriptor&& other)
121 {
122 basic_io_object<DescriptorService>::operator=(
123 BOOST_ASIO_MOVE_CAST(basic_descriptor)(other));
124 return *this;
125 }
126 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
127
128 /// Get a reference to the lowest layer.
129 /**
130 * This function returns a reference to the lowest layer in a stack of
131 * layers. Since a basic_descriptor cannot contain any further layers, it
132 * simply returns a reference to itself.
133 *
134 * @return A reference to the lowest layer in the stack of layers. Ownership
135 * is not transferred to the caller.
136 */
137 lowest_layer_type& lowest_layer()
138 {
139 return *this;
140 }
141
142 /// Get a const reference to the lowest layer.
143 /**
144 * This function returns a const reference to the lowest layer in a stack of
145 * layers. Since a basic_descriptor cannot contain any further layers, it
146 * simply returns a reference to itself.
147 *
148 * @return A const reference to the lowest layer in the stack of layers.
149 * Ownership is not transferred to the caller.
150 */
151 const lowest_layer_type& lowest_layer() const
152 {
153 return *this;
154 }
155
156 /// Assign an existing native descriptor to the descriptor.
157 /*
158 * This function opens the descriptor to hold an existing native descriptor.
159 *
160 * @param native_descriptor A native descriptor.
161 *
162 * @throws boost::system::system_error Thrown on failure.
163 */
164 void assign(const native_handle_type& native_descriptor)
165 {
166 boost::system::error_code ec;
167 this->get_service().assign(this->get_implementation(),
168 native_descriptor, ec);
169 boost::asio::detail::throw_error(ec, "assign");
170 }
171
172 /// Assign an existing native descriptor to the descriptor.
173 /*
174 * This function opens the descriptor to hold an existing native descriptor.
175 *
176 * @param native_descriptor A native descriptor.
177 *
178 * @param ec Set to indicate what error occurred, if any.
179 */
180 BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor,
181 boost::system::error_code& ec)
182 {
183 this->get_service().assign(
184 this->get_implementation(), native_descriptor, ec);
185 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
186 }
187
188 /// Determine whether the descriptor is open.
189 bool is_open() const
190 {
191 return this->get_service().is_open(this->get_implementation());
192 }
193
194 /// Close the descriptor.
195 /**
196 * This function is used to close the descriptor. Any asynchronous read or
197 * write operations will be cancelled immediately, and will complete with the
198 * boost::asio::error::operation_aborted error.
199 *
200 * @throws boost::system::system_error Thrown on failure. Note that, even if
201 * the function indicates an error, the underlying descriptor is closed.
202 */
203 void close()
204 {
205 boost::system::error_code ec;
206 this->get_service().close(this->get_implementation(), ec);
207 boost::asio::detail::throw_error(ec, "close");
208 }
209
210 /// Close the descriptor.
211 /**
212 * This function is used to close the descriptor. Any asynchronous read or
213 * write operations will be cancelled immediately, and will complete with the
214 * boost::asio::error::operation_aborted error.
215 *
216 * @param ec Set to indicate what error occurred, if any. Note that, even if
217 * the function indicates an error, the underlying descriptor is closed.
218 */
219 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
220 {
221 this->get_service().close(this->get_implementation(), ec);
222 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
223 }
224
225 /// Get the native descriptor representation.
226 /**
227 * This function may be used to obtain the underlying representation of the
228 * descriptor. This is intended to allow access to native descriptor
229 * functionality that is not otherwise provided.
230 */
231 native_handle_type native_handle()
232 {
233 return this->get_service().native_handle(this->get_implementation());
234 }
235
236 /// Release ownership of the native descriptor implementation.
237 /**
238 * This function may be used to obtain the underlying representation of the
239 * descriptor. After calling this function, @c is_open() returns false. The
240 * caller is responsible for closing the descriptor.
241 *
242 * All outstanding asynchronous read or write operations will finish
243 * immediately, and the handlers for cancelled operations will be passed the
244 * boost::asio::error::operation_aborted error.
245 */
246 native_handle_type release()
247 {
248 return this->get_service().release(this->get_implementation());
249 }
250
251 /// Cancel all asynchronous operations associated with the descriptor.
252 /**
253 * This function causes all outstanding asynchronous read or write operations
254 * to finish immediately, and the handlers for cancelled operations will be
255 * passed the boost::asio::error::operation_aborted error.
256 *
257 * @throws boost::system::system_error Thrown on failure.
258 */
259 void cancel()
260 {
261 boost::system::error_code ec;
262 this->get_service().cancel(this->get_implementation(), ec);
263 boost::asio::detail::throw_error(ec, "cancel");
264 }
265
266 /// Cancel all asynchronous operations associated with the descriptor.
267 /**
268 * This function causes all outstanding asynchronous read or write operations
269 * to finish immediately, and the handlers for cancelled operations will be
270 * passed the boost::asio::error::operation_aborted error.
271 *
272 * @param ec Set to indicate what error occurred, if any.
273 */
274 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
275 {
276 this->get_service().cancel(this->get_implementation(), ec);
277 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
278 }
279
280 /// Perform an IO control command on the descriptor.
281 /**
282 * This function is used to execute an IO control command on the descriptor.
283 *
284 * @param command The IO control command to be performed on the descriptor.
285 *
286 * @throws boost::system::system_error Thrown on failure.
287 *
288 * @sa IoControlCommand @n
289 * boost::asio::posix::descriptor_base::bytes_readable @n
290 * boost::asio::posix::descriptor_base::non_blocking_io
291 *
292 * @par Example
293 * Getting the number of bytes ready to read:
294 * @code
295 * boost::asio::posix::stream_descriptor descriptor(io_context);
296 * ...
297 * boost::asio::posix::stream_descriptor::bytes_readable command;
298 * descriptor.io_control(command);
299 * std::size_t bytes_readable = command.get();
300 * @endcode
301 */
302 template <typename IoControlCommand>
303 void io_control(IoControlCommand& command)
304 {
305 boost::system::error_code ec;
306 this->get_service().io_control(this->get_implementation(), command, ec);
307 boost::asio::detail::throw_error(ec, "io_control");
308 }
309
310 /// Perform an IO control command on the descriptor.
311 /**
312 * This function is used to execute an IO control command on the descriptor.
313 *
314 * @param command The IO control command to be performed on the descriptor.
315 *
316 * @param ec Set to indicate what error occurred, if any.
317 *
318 * @sa IoControlCommand @n
319 * boost::asio::posix::descriptor_base::bytes_readable @n
320 * boost::asio::posix::descriptor_base::non_blocking_io
321 *
322 * @par Example
323 * Getting the number of bytes ready to read:
324 * @code
325 * boost::asio::posix::stream_descriptor descriptor(io_context);
326 * ...
327 * boost::asio::posix::stream_descriptor::bytes_readable command;
328 * boost::system::error_code ec;
329 * descriptor.io_control(command, ec);
330 * if (ec)
331 * {
332 * // An error occurred.
333 * }
334 * std::size_t bytes_readable = command.get();
335 * @endcode
336 */
337 template <typename IoControlCommand>
338 BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
339 boost::system::error_code& ec)
340 {
341 this->get_service().io_control(this->get_implementation(), command, ec);
342 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
343 }
344
345 /// Gets the non-blocking mode of the descriptor.
346 /**
347 * @returns @c true if the descriptor's synchronous operations will fail with
348 * boost::asio::error::would_block if they are unable to perform the requested
349 * operation immediately. If @c false, synchronous operations will block
350 * until complete.
351 *
352 * @note The non-blocking mode has no effect on the behaviour of asynchronous
353 * operations. Asynchronous operations will never fail with the error
354 * boost::asio::error::would_block.
355 */
356 bool non_blocking() const
357 {
358 return this->get_service().non_blocking(this->get_implementation());
359 }
360
361 /// Sets the non-blocking mode of the descriptor.
362 /**
363 * @param mode If @c true, the descriptor's synchronous operations will fail
364 * with boost::asio::error::would_block if they are unable to perform the
365 * requested operation immediately. If @c false, synchronous operations will
366 * block until complete.
367 *
368 * @throws boost::system::system_error Thrown on failure.
369 *
370 * @note The non-blocking mode has no effect on the behaviour of asynchronous
371 * operations. Asynchronous operations will never fail with the error
372 * boost::asio::error::would_block.
373 */
374 void non_blocking(bool mode)
375 {
376 boost::system::error_code ec;
377 this->get_service().non_blocking(this->get_implementation(), mode, ec);
378 boost::asio::detail::throw_error(ec, "non_blocking");
379 }
380
381 /// Sets the non-blocking mode of the descriptor.
382 /**
383 * @param mode If @c true, the descriptor's synchronous operations will fail
384 * with boost::asio::error::would_block if they are unable to perform the
385 * requested operation immediately. If @c false, synchronous operations will
386 * block until complete.
387 *
388 * @param ec Set to indicate what error occurred, if any.
389 *
390 * @note The non-blocking mode has no effect on the behaviour of asynchronous
391 * operations. Asynchronous operations will never fail with the error
392 * boost::asio::error::would_block.
393 */
394 BOOST_ASIO_SYNC_OP_VOID non_blocking(
395 bool mode, boost::system::error_code& ec)
396 {
397 this->get_service().non_blocking(this->get_implementation(), mode, ec);
398 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
399 }
400
401 /// Gets the non-blocking mode of the native descriptor implementation.
402 /**
403 * This function is used to retrieve the non-blocking mode of the underlying
404 * native descriptor. This mode has no effect on the behaviour of the
405 * descriptor object's synchronous operations.
406 *
407 * @returns @c true if the underlying descriptor is in non-blocking mode and
408 * direct system calls may fail with boost::asio::error::would_block (or the
409 * equivalent system error).
410 *
411 * @note The current non-blocking mode is cached by the descriptor object.
412 * Consequently, the return value may be incorrect if the non-blocking mode
413 * was set directly on the native descriptor.
414 */
415 bool native_non_blocking() const
416 {
417 return this->get_service().native_non_blocking(
418 this->get_implementation());
419 }
420
421 /// Sets the non-blocking mode of the native descriptor implementation.
422 /**
423 * This function is used to modify the non-blocking mode of the underlying
424 * native descriptor. It has no effect on the behaviour of the descriptor
425 * object's synchronous operations.
426 *
427 * @param mode If @c true, the underlying descriptor is put into non-blocking
428 * mode and direct system calls may fail with boost::asio::error::would_block
429 * (or the equivalent system error).
430 *
431 * @throws boost::system::system_error Thrown on failure. If the @c mode is
432 * @c false, but the current value of @c non_blocking() is @c true, this
433 * function fails with boost::asio::error::invalid_argument, as the
434 * combination does not make sense.
435 */
436 void native_non_blocking(bool mode)
437 {
438 boost::system::error_code ec;
439 this->get_service().native_non_blocking(
440 this->get_implementation(), mode, ec);
441 boost::asio::detail::throw_error(ec, "native_non_blocking");
442 }
443
444 /// Sets the non-blocking mode of the native descriptor implementation.
445 /**
446 * This function is used to modify the non-blocking mode of the underlying
447 * native descriptor. It has no effect on the behaviour of the descriptor
448 * object's synchronous operations.
449 *
450 * @param mode If @c true, the underlying descriptor is put into non-blocking
451 * mode and direct system calls may fail with boost::asio::error::would_block
452 * (or the equivalent system error).
453 *
454 * @param ec Set to indicate what error occurred, if any. If the @c mode is
455 * @c false, but the current value of @c non_blocking() is @c true, this
456 * function fails with boost::asio::error::invalid_argument, as the
457 * combination does not make sense.
458 */
459 BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
460 bool mode, boost::system::error_code& ec)
461 {
462 this->get_service().native_non_blocking(
463 this->get_implementation(), mode, ec);
464 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
465 }
466
467 /// Wait for the descriptor to become ready to read, ready to write, or to
468 /// have pending error conditions.
469 /**
470 * This function is used to perform a blocking wait for a descriptor to enter
471 * a ready to read, write or error condition state.
472 *
473 * @param w Specifies the desired descriptor state.
474 *
475 * @par Example
476 * Waiting for a descriptor to become readable.
477 * @code
478 * boost::asio::posix::stream_descriptor descriptor(io_context);
479 * ...
480 * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read);
481 * @endcode
482 */
483 void wait(wait_type w)
484 {
485 boost::system::error_code ec;
486 this->get_service().wait(this->get_implementation(), w, ec);
487 boost::asio::detail::throw_error(ec, "wait");
488 }
489
490 /// Wait for the descriptor to become ready to read, ready to write, or to
491 /// have pending error conditions.
492 /**
493 * This function is used to perform a blocking wait for a descriptor to enter
494 * a ready to read, write or error condition state.
495 *
496 * @param w Specifies the desired descriptor state.
497 *
498 * @param ec Set to indicate what error occurred, if any.
499 *
500 * @par Example
501 * Waiting for a descriptor to become readable.
502 * @code
503 * boost::asio::posix::stream_descriptor descriptor(io_context);
504 * ...
505 * boost::system::error_code ec;
506 * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read, ec);
507 * @endcode
508 */
509 BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
510 {
511 this->get_service().wait(this->get_implementation(), w, ec);
512 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
513 }
514
515 /// Asynchronously wait for the descriptor to become ready to read, ready to
516 /// write, or to have pending error conditions.
517 /**
518 * This function is used to perform an asynchronous wait for a descriptor to
519 * enter a ready to read, write or error condition state.
520 *
521 * @param w Specifies the desired descriptor state.
522 *
523 * @param handler The handler to be called when the wait operation completes.
524 * Copies will be made of the handler as required. The function signature of
525 * the handler must be:
526 * @code void handler(
527 * const boost::system::error_code& error // Result of operation
528 * ); @endcode
529 * Regardless of whether the asynchronous operation completes immediately or
530 * not, the handler will not be invoked from within this function. Invocation
531 * of the handler will be performed in a manner equivalent to using
532 * boost::asio::io_context::post().
533 *
534 * @par Example
535 * @code
536 * void wait_handler(const boost::system::error_code& error)
537 * {
538 * if (!error)
539 * {
540 * // Wait succeeded.
541 * }
542 * }
543 *
544 * ...
545 *
546 * boost::asio::posix::stream_descriptor descriptor(io_context);
547 * ...
548 * descriptor.async_wait(
549 * boost::asio::posix::stream_descriptor::wait_read,
550 * wait_handler);
551 * @endcode
552 */
553 template <typename WaitHandler>
554 BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
555 void (boost::system::error_code))
556 async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
557 {
558 // If you get an error on the following line it means that your handler does
559 // not meet the documented type requirements for a WaitHandler.
560 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
561
562 return this->get_service().async_wait(this->get_implementation(),
563 w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
564 }
565
566 protected:
567 /// Protected destructor to prevent deletion through this type.
568 ~basic_descriptor()
569 {
570 }
571 };
572
573 } // namespace posix
574 } // namespace asio
575 } // namespace boost
576
577 #include <boost/asio/detail/pop_options.hpp>
578
579 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
580 // || defined(GENERATING_DOCUMENTATION)
581
582 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
583
584 #endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP