]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/windows/basic_stream_handle.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / asio / windows / basic_stream_handle.hpp
1 //
2 // windows/basic_stream_handle.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_WINDOWS_BASIC_STREAM_HANDLE_HPP
12 #define BOOST_ASIO_WINDOWS_BASIC_STREAM_HANDLE_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 #include <boost/asio/windows/basic_overlapped_handle.hpp>
20
21 #if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
22 || defined(GENERATING_DOCUMENTATION)
23
24 #include <boost/asio/detail/push_options.hpp>
25
26 namespace boost {
27 namespace asio {
28 namespace windows {
29
30 /// Provides stream-oriented handle functionality.
31 /**
32 * The windows::basic_stream_handle class provides asynchronous and blocking
33 * stream-oriented handle functionality.
34 *
35 * @par Thread Safety
36 * @e Distinct @e objects: Safe.@n
37 * @e Shared @e objects: Unsafe.
38 *
39 * @par Concepts:
40 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
41 */
42 template <typename Executor = any_io_executor>
43 class basic_stream_handle
44 : public basic_overlapped_handle<Executor>
45 {
46 public:
47 /// The type of the executor associated with the object.
48 typedef Executor executor_type;
49
50 /// Rebinds the handle type to another executor.
51 template <typename Executor1>
52 struct rebind_executor
53 {
54 /// The handle type when rebound to the specified executor.
55 typedef basic_stream_handle<Executor1> other;
56 };
57
58 /// The native representation of a handle.
59 #if defined(GENERATING_DOCUMENTATION)
60 typedef implementation_defined native_handle_type;
61 #else
62 typedef boost::asio::detail::win_iocp_handle_service::native_handle_type
63 native_handle_type;
64 #endif
65
66 /// Construct a stream handle without opening it.
67 /**
68 * This constructor creates a stream handle without opening it.
69 *
70 * @param ex The I/O executor that the stream handle will use, by default, to
71 * dispatch handlers for any asynchronous operations performed on the stream
72 * handle.
73 */
74 explicit basic_stream_handle(const executor_type& ex)
75 : basic_overlapped_handle<Executor>(ex)
76 {
77 }
78
79 /// Construct a stream handle without opening it.
80 /**
81 * This constructor creates a stream handle without opening it. The handle
82 * needs to be opened or assigned before data can be written to or read from
83 * it.
84 *
85 * @param context An execution context which provides the I/O executor that
86 * the stream handle will use, by default, to dispatch handlers for any
87 * asynchronous operations performed on the stream handle.
88 */
89 template <typename ExecutionContext>
90 explicit basic_stream_handle(ExecutionContext& context,
91 typename constraint<
92 is_convertible<ExecutionContext&, execution_context&>::value,
93 defaulted_constraint
94 >::type = defaulted_constraint())
95 : basic_overlapped_handle<Executor>(context)
96 {
97 }
98
99 /// Construct a stream handle on an existing native handle.
100 /**
101 * This constructor creates a stream handle object to hold an existing native
102 * handle.
103 *
104 * @param ex The I/O executor that the stream handle will use, by default, to
105 * dispatch handlers for any asynchronous operations performed on the stream
106 * handle.
107 *
108 * @param handle The new underlying handle implementation.
109 *
110 * @throws boost::system::system_error Thrown on failure.
111 */
112 basic_stream_handle(const executor_type& ex, const native_handle_type& handle)
113 : basic_overlapped_handle<Executor>(ex, handle)
114 {
115 }
116
117 /// Construct a stream handle on an existing native handle.
118 /**
119 * This constructor creates a stream handle object to hold an existing native
120 * handle.
121 *
122 * @param context An execution context which provides the I/O executor that
123 * the stream handle will use, by default, to dispatch handlers for any
124 * asynchronous operations performed on the stream handle.
125 *
126 * @param handle The new underlying handle implementation.
127 *
128 * @throws boost::system::system_error Thrown on failure.
129 */
130 template <typename ExecutionContext>
131 basic_stream_handle(ExecutionContext& context,
132 const native_handle_type& handle,
133 typename constraint<
134 is_convertible<ExecutionContext&, execution_context&>::value
135 >::type = 0)
136 : basic_overlapped_handle<Executor>(context, handle)
137 {
138 }
139
140 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
141 /// Move-construct a stream handle from another.
142 /**
143 * This constructor moves a stream handle from one object to another.
144 *
145 * @param other The other stream handle object from which the move
146 * will occur.
147 *
148 * @note Following the move, the moved-from object is in the same state as if
149 * constructed using the @c basic_stream_handle(const executor_type&)
150 * constructor.
151 */
152 basic_stream_handle(basic_stream_handle&& other)
153 : basic_overlapped_handle<Executor>(std::move(other))
154 {
155 }
156
157 /// Move-assign a stream handle from another.
158 /**
159 * This assignment operator moves a stream handle from one object to
160 * another.
161 *
162 * @param other The other stream handle object from which the move will occur.
163 *
164 * @note Following the move, the moved-from object is in the same state as if
165 * constructed using the @c basic_stream_handle(const executor_type&)
166 * constructor.
167 */
168 basic_stream_handle& operator=(basic_stream_handle&& other)
169 {
170 basic_overlapped_handle<Executor>::operator=(std::move(other));
171 return *this;
172 }
173 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
174
175 /// Write some data to the handle.
176 /**
177 * This function is used to write data to the stream handle. The function call
178 * will block until one or more bytes of the data has been written
179 * successfully, or until an error occurs.
180 *
181 * @param buffers One or more data buffers to be written to the handle.
182 *
183 * @returns The number of bytes written.
184 *
185 * @throws boost::system::system_error Thrown on failure. An error code of
186 * boost::asio::error::eof indicates that the connection was closed by the
187 * peer.
188 *
189 * @note The write_some operation may not transmit all of the data to the
190 * peer. Consider using the @ref write function if you need to ensure that
191 * all data is written before the blocking operation completes.
192 *
193 * @par Example
194 * To write a single data buffer use the @ref buffer function as follows:
195 * @code
196 * handle.write_some(boost::asio::buffer(data, size));
197 * @endcode
198 * See the @ref buffer documentation for information on writing multiple
199 * buffers in one go, and how to use it with arrays, boost::array or
200 * std::vector.
201 */
202 template <typename ConstBufferSequence>
203 std::size_t write_some(const ConstBufferSequence& buffers)
204 {
205 boost::system::error_code ec;
206 std::size_t s = this->impl_.get_service().write_some(
207 this->impl_.get_implementation(), buffers, ec);
208 boost::asio::detail::throw_error(ec, "write_some");
209 return s;
210 }
211
212 /// Write some data to the handle.
213 /**
214 * This function is used to write data to the stream handle. The function call
215 * will block until one or more bytes of the data has been written
216 * successfully, or until an error occurs.
217 *
218 * @param buffers One or more data buffers to be written to the handle.
219 *
220 * @param ec Set to indicate what error occurred, if any.
221 *
222 * @returns The number of bytes written. Returns 0 if an error occurred.
223 *
224 * @note The write_some operation may not transmit all of the data to the
225 * peer. Consider using the @ref write function if you need to ensure that
226 * all data is written before the blocking operation completes.
227 */
228 template <typename ConstBufferSequence>
229 std::size_t write_some(const ConstBufferSequence& buffers,
230 boost::system::error_code& ec)
231 {
232 return this->impl_.get_service().write_some(
233 this->impl_.get_implementation(), buffers, ec);
234 }
235
236 /// Start an asynchronous write.
237 /**
238 * This function is used to asynchronously write data to the stream handle.
239 * It is an initiating function for an @ref asynchronous_operation, and always
240 * returns immediately.
241 *
242 * @param buffers One or more data buffers to be written to the handle.
243 * Although the buffers object may be copied as necessary, ownership of the
244 * underlying memory blocks is retained by the caller, which must guarantee
245 * that they remain valid until the completion handler is called.
246 *
247 * @param token The @ref completion_token that will be used to produce a
248 * completion handler, which will be called when the write completes.
249 * Potential completion tokens include @ref use_future, @ref use_awaitable,
250 * @ref yield_context, or a function object with the correct completion
251 * signature. The function signature of the completion handler must be:
252 * @code void handler(
253 * const boost::system::error_code& error, // Result of operation.
254 * std::size_t bytes_transferred // Number of bytes written.
255 * ); @endcode
256 * Regardless of whether the asynchronous operation completes immediately or
257 * not, the completion handler will not be invoked from within this function.
258 * On immediate completion, invocation of the handler will be performed in a
259 * manner equivalent to using boost::asio::post().
260 *
261 * @par Completion Signature
262 * @code void(boost::system::error_code, std::size_t) @endcode
263 *
264 * @note The write operation may not transmit all of the data to the peer.
265 * Consider using the @ref async_write function if you need to ensure that all
266 * data is written before the asynchronous operation completes.
267 *
268 * @par Example
269 * To write a single data buffer use the @ref buffer function as follows:
270 * @code
271 * handle.async_write_some(boost::asio::buffer(data, size), handler);
272 * @endcode
273 * See the @ref buffer documentation for information on writing multiple
274 * buffers in one go, and how to use it with arrays, boost::array or
275 * std::vector.
276 *
277 * @par Per-Operation Cancellation
278 * This asynchronous operation supports cancellation for the following
279 * boost::asio::cancellation_type values:
280 *
281 * @li @c cancellation_type::terminal
282 *
283 * @li @c cancellation_type::partial
284 *
285 * @li @c cancellation_type::total
286 */
287 template <typename ConstBufferSequence,
288 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
289 std::size_t)) WriteToken
290 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
291 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteToken,
292 void (boost::system::error_code, std::size_t))
293 async_write_some(const ConstBufferSequence& buffers,
294 BOOST_ASIO_MOVE_ARG(WriteToken) token
295 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
296 {
297 return async_initiate<WriteToken,
298 void (boost::system::error_code, std::size_t)>(
299 initiate_async_write_some(this), token, buffers);
300 }
301
302 /// Read some data from the handle.
303 /**
304 * This function is used to read data from the stream handle. The function
305 * call will block until one or more bytes of data has been read successfully,
306 * or until an error occurs.
307 *
308 * @param buffers One or more buffers into which the data will be read.
309 *
310 * @returns The number of bytes read.
311 *
312 * @throws boost::system::system_error Thrown on failure. An error code of
313 * boost::asio::error::eof indicates that the connection was closed by the
314 * peer.
315 *
316 * @note The read_some operation may not read all of the requested number of
317 * bytes. Consider using the @ref read function if you need to ensure that
318 * the requested amount of data is read before the blocking operation
319 * completes.
320 *
321 * @par Example
322 * To read into a single data buffer use the @ref buffer function as follows:
323 * @code
324 * handle.read_some(boost::asio::buffer(data, size));
325 * @endcode
326 * See the @ref buffer documentation for information on reading into multiple
327 * buffers in one go, and how to use it with arrays, boost::array or
328 * std::vector.
329 */
330 template <typename MutableBufferSequence>
331 std::size_t read_some(const MutableBufferSequence& buffers)
332 {
333 boost::system::error_code ec;
334 std::size_t s = this->impl_.get_service().read_some(
335 this->impl_.get_implementation(), buffers, ec);
336 boost::asio::detail::throw_error(ec, "read_some");
337 return s;
338 }
339
340 /// Read some data from the handle.
341 /**
342 * This function is used to read data from the stream handle. The function
343 * call will block until one or more bytes of data has been read successfully,
344 * or until an error occurs.
345 *
346 * @param buffers One or more buffers into which the data will be read.
347 *
348 * @param ec Set to indicate what error occurred, if any.
349 *
350 * @returns The number of bytes read. Returns 0 if an error occurred.
351 *
352 * @note The read_some operation may not read all of the requested number of
353 * bytes. Consider using the @ref read function if you need to ensure that
354 * the requested amount of data is read before the blocking operation
355 * completes.
356 */
357 template <typename MutableBufferSequence>
358 std::size_t read_some(const MutableBufferSequence& buffers,
359 boost::system::error_code& ec)
360 {
361 return this->impl_.get_service().read_some(
362 this->impl_.get_implementation(), buffers, ec);
363 }
364
365 /// Start an asynchronous read.
366 /**
367 * This function is used to asynchronously read data from the stream handle.
368 * It is an initiating function for an @ref asynchronous_operation, and always
369 * returns immediately.
370 *
371 * @param buffers One or more buffers into which the data will be read.
372 * Although the buffers object may be copied as necessary, ownership of the
373 * underlying memory blocks is retained by the caller, which must guarantee
374 * that they remain valid until the completion handler is called.
375 *
376 * @param token The @ref completion_token that will be used to produce a
377 * completion handler, which will be called when the read completes.
378 * Potential completion tokens include @ref use_future, @ref use_awaitable,
379 * @ref yield_context, or a function object with the correct completion
380 * signature. The function signature of the completion handler must be:
381 * @code void handler(
382 * const boost::system::error_code& error, // Result of operation.
383 * std::size_t bytes_transferred // Number of bytes read.
384 * ); @endcode
385 * Regardless of whether the asynchronous operation completes immediately or
386 * not, the completion handler will not be invoked from within this function.
387 * On immediate completion, invocation of the handler will be performed in a
388 * manner equivalent to using boost::asio::post().
389 *
390 * @par Completion Signature
391 * @code void(boost::system::error_code, std::size_t) @endcode
392 *
393 * @note The read operation may not read all of the requested number of bytes.
394 * Consider using the @ref async_read function if you need to ensure that the
395 * requested amount of data is read before the asynchronous operation
396 * completes.
397 *
398 * @par Example
399 * To read into a single data buffer use the @ref buffer function as follows:
400 * @code
401 * handle.async_read_some(boost::asio::buffer(data, size), handler);
402 * @endcode
403 * See the @ref buffer documentation for information on reading into multiple
404 * buffers in one go, and how to use it with arrays, boost::array or
405 * std::vector.
406 *
407 * @par Per-Operation Cancellation
408 * This asynchronous operation supports cancellation for the following
409 * boost::asio::cancellation_type values:
410 *
411 * @li @c cancellation_type::terminal
412 *
413 * @li @c cancellation_type::partial
414 *
415 * @li @c cancellation_type::total
416 */
417 template <typename MutableBufferSequence,
418 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
419 std::size_t)) ReadToken
420 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
421 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
422 void (boost::system::error_code, std::size_t))
423 async_read_some(const MutableBufferSequence& buffers,
424 BOOST_ASIO_MOVE_ARG(ReadToken) token
425 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
426 {
427 return async_initiate<ReadToken,
428 void (boost::system::error_code, std::size_t)>(
429 initiate_async_read_some(this), token, buffers);
430 }
431
432 private:
433 class initiate_async_write_some
434 {
435 public:
436 typedef Executor executor_type;
437
438 explicit initiate_async_write_some(basic_stream_handle* self)
439 : self_(self)
440 {
441 }
442
443 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
444 {
445 return self_->get_executor();
446 }
447
448 template <typename WriteHandler, typename ConstBufferSequence>
449 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
450 const ConstBufferSequence& buffers) const
451 {
452 // If you get an error on the following line it means that your handler
453 // does not meet the documented type requirements for a WriteHandler.
454 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
455
456 detail::non_const_lvalue<WriteHandler> handler2(handler);
457 self_->impl_.get_service().async_write_some(
458 self_->impl_.get_implementation(), buffers,
459 handler2.value, self_->impl_.get_executor());
460 }
461
462 private:
463 basic_stream_handle* self_;
464 };
465
466 class initiate_async_read_some
467 {
468 public:
469 typedef Executor executor_type;
470
471 explicit initiate_async_read_some(basic_stream_handle* self)
472 : self_(self)
473 {
474 }
475
476 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
477 {
478 return self_->get_executor();
479 }
480
481 template <typename ReadHandler, typename MutableBufferSequence>
482 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
483 const MutableBufferSequence& buffers) const
484 {
485 // If you get an error on the following line it means that your handler
486 // does not meet the documented type requirements for a ReadHandler.
487 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
488
489 detail::non_const_lvalue<ReadHandler> handler2(handler);
490 self_->impl_.get_service().async_read_some(
491 self_->impl_.get_implementation(), buffers,
492 handler2.value, self_->impl_.get_executor());
493 }
494
495 private:
496 basic_stream_handle* self_;
497 };
498 };
499
500 } // namespace windows
501 } // namespace asio
502 } // namespace boost
503
504 #include <boost/asio/detail/pop_options.hpp>
505
506 #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
507 // || defined(GENERATING_DOCUMENTATION)
508
509 #endif // BOOST_ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP