]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/windows/basic_object_handle.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / windows / basic_object_handle.hpp
1 //
2 // windows/basic_object_handle.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 // Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11
12 #ifndef BOOST_ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP
13 #define BOOST_ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP
14
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
19 #include <boost/asio/detail/config.hpp>
20
21 #if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
22 || defined(GENERATING_DOCUMENTATION)
23
24 #include <boost/asio/any_io_executor.hpp>
25 #include <boost/asio/async_result.hpp>
26 #include <boost/asio/detail/io_object_impl.hpp>
27 #include <boost/asio/detail/throw_error.hpp>
28 #include <boost/asio/detail/win_object_handle_service.hpp>
29 #include <boost/asio/error.hpp>
30 #include <boost/asio/execution_context.hpp>
31
32 #if defined(BOOST_ASIO_HAS_MOVE)
33 # include <utility>
34 #endif // defined(BOOST_ASIO_HAS_MOVE)
35
36 #include <boost/asio/detail/push_options.hpp>
37
38 namespace boost {
39 namespace asio {
40 namespace windows {
41
42 /// Provides object-oriented handle functionality.
43 /**
44 * The windows::basic_object_handle class provides asynchronous and blocking
45 * object-oriented handle functionality.
46 *
47 * @par Thread Safety
48 * @e Distinct @e objects: Safe.@n
49 * @e Shared @e objects: Unsafe.
50 */
51 template <typename Executor = any_io_executor>
52 class basic_object_handle
53 {
54 public:
55 /// The type of the executor associated with the object.
56 typedef Executor executor_type;
57
58 /// Rebinds the handle type to another executor.
59 template <typename Executor1>
60 struct rebind_executor
61 {
62 /// The handle type when rebound to the specified executor.
63 typedef basic_object_handle<Executor1> other;
64 };
65
66 /// The native representation of a handle.
67 #if defined(GENERATING_DOCUMENTATION)
68 typedef implementation_defined native_handle_type;
69 #else
70 typedef boost::asio::detail::win_object_handle_service::native_handle_type
71 native_handle_type;
72 #endif
73
74 /// An object handle is always the lowest layer.
75 typedef basic_object_handle lowest_layer_type;
76
77 /// Construct an object handle without opening it.
78 /**
79 * This constructor creates an object handle without opening it.
80 *
81 * @param ex The I/O executor that the object handle will use, by default, to
82 * dispatch handlers for any asynchronous operations performed on the
83 * object handle.
84 */
85 explicit basic_object_handle(const executor_type& ex)
86 : impl_(0, ex)
87 {
88 }
89
90 /// Construct an object handle without opening it.
91 /**
92 * This constructor creates an object handle without opening it.
93 *
94 * @param context An execution context which provides the I/O executor that
95 * the object handle will use, by default, to dispatch handlers for any
96 * asynchronous operations performed on the object handle.
97 */
98 template <typename ExecutionContext>
99 explicit basic_object_handle(ExecutionContext& context,
100 typename constraint<
101 is_convertible<ExecutionContext&, execution_context&>::value,
102 defaulted_constraint
103 >::type = defaulted_constraint())
104 : impl_(0, 0, context)
105 {
106 }
107
108 /// Construct an object handle on an existing native handle.
109 /**
110 * This constructor creates an object handle object to hold an existing native
111 * handle.
112 *
113 * @param ex The I/O executor that the object handle will use, by default, to
114 * dispatch handlers for any asynchronous operations performed on the
115 * object handle.
116 *
117 * @param native_handle The new underlying handle implementation.
118 *
119 * @throws boost::system::system_error Thrown on failure.
120 */
121 basic_object_handle(const executor_type& ex,
122 const native_handle_type& native_handle)
123 : impl_(0, ex)
124 {
125 boost::system::error_code ec;
126 impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
127 boost::asio::detail::throw_error(ec, "assign");
128 }
129
130 /// Construct an object handle on an existing native handle.
131 /**
132 * This constructor creates an object handle object to hold an existing native
133 * handle.
134 *
135 * @param context An execution context which provides the I/O executor that
136 * the object handle will use, by default, to dispatch handlers for any
137 * asynchronous operations performed on the object handle.
138 *
139 * @param native_handle The new underlying handle implementation.
140 *
141 * @throws boost::system::system_error Thrown on failure.
142 */
143 template <typename ExecutionContext>
144 basic_object_handle(ExecutionContext& context,
145 const native_handle_type& native_handle,
146 typename constraint<
147 is_convertible<ExecutionContext&, execution_context&>::value
148 >::type = 0)
149 : impl_(0, 0, context)
150 {
151 boost::system::error_code ec;
152 impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
153 boost::asio::detail::throw_error(ec, "assign");
154 }
155
156 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
157 /// Move-construct an object handle from another.
158 /**
159 * This constructor moves an object handle from one object to another.
160 *
161 * @param other The other object handle object from which the move will
162 * occur.
163 *
164 * @note Following the move, the moved-from object is in the same state as if
165 * constructed using the @c basic_object_handle(const executor_type&)
166 * constructor.
167 */
168 basic_object_handle(basic_object_handle&& other)
169 : impl_(std::move(other.impl_))
170 {
171 }
172
173 /// Move-assign an object handle from another.
174 /**
175 * This assignment operator moves an object handle from one object to another.
176 *
177 * @param other The other object handle object from which the move will
178 * occur.
179 *
180 * @note Following the move, the moved-from object is in the same state as if
181 * constructed using the @c basic_object_handle(const executor_type&)
182 * constructor.
183 */
184 basic_object_handle& operator=(basic_object_handle&& other)
185 {
186 impl_ = std::move(other.impl_);
187 return *this;
188 }
189 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
190
191 /// Get the executor associated with the object.
192 executor_type get_executor() BOOST_ASIO_NOEXCEPT
193 {
194 return impl_.get_executor();
195 }
196
197 /// Get a reference to the lowest layer.
198 /**
199 * This function returns a reference to the lowest layer in a stack of
200 * layers. Since an object handle cannot contain any further layers, it simply
201 * returns a reference to itself.
202 *
203 * @return A reference to the lowest layer in the stack of layers. Ownership
204 * is not transferred to the caller.
205 */
206 lowest_layer_type& lowest_layer()
207 {
208 return *this;
209 }
210
211 /// Get a const reference to the lowest layer.
212 /**
213 * This function returns a const reference to the lowest layer in a stack of
214 * layers. Since an object handle cannot contain any further layers, it simply
215 * returns a reference to itself.
216 *
217 * @return A const reference to the lowest layer in the stack of layers.
218 * Ownership is not transferred to the caller.
219 */
220 const lowest_layer_type& lowest_layer() const
221 {
222 return *this;
223 }
224
225 /// Assign an existing native handle to the handle.
226 /*
227 * This function opens the handle to hold an existing native handle.
228 *
229 * @param handle A native handle.
230 *
231 * @throws boost::system::system_error Thrown on failure.
232 */
233 void assign(const native_handle_type& handle)
234 {
235 boost::system::error_code ec;
236 impl_.get_service().assign(impl_.get_implementation(), handle, ec);
237 boost::asio::detail::throw_error(ec, "assign");
238 }
239
240 /// Assign an existing native handle to the handle.
241 /*
242 * This function opens the handle to hold an existing native handle.
243 *
244 * @param handle A native handle.
245 *
246 * @param ec Set to indicate what error occurred, if any.
247 */
248 BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
249 boost::system::error_code& ec)
250 {
251 impl_.get_service().assign(impl_.get_implementation(), handle, ec);
252 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
253 }
254
255 /// Determine whether the handle is open.
256 bool is_open() const
257 {
258 return impl_.get_service().is_open(impl_.get_implementation());
259 }
260
261 /// Close the handle.
262 /**
263 * This function is used to close the handle. Any asynchronous read or write
264 * operations will be cancelled immediately, and will complete with the
265 * boost::asio::error::operation_aborted error.
266 *
267 * @throws boost::system::system_error Thrown on failure.
268 */
269 void close()
270 {
271 boost::system::error_code ec;
272 impl_.get_service().close(impl_.get_implementation(), ec);
273 boost::asio::detail::throw_error(ec, "close");
274 }
275
276 /// Close the handle.
277 /**
278 * This function is used to close the handle. Any asynchronous read or write
279 * operations will be cancelled immediately, and will complete with the
280 * boost::asio::error::operation_aborted error.
281 *
282 * @param ec Set to indicate what error occurred, if any.
283 */
284 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
285 {
286 impl_.get_service().close(impl_.get_implementation(), ec);
287 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
288 }
289
290 /// Get the native handle representation.
291 /**
292 * This function may be used to obtain the underlying representation of the
293 * handle. This is intended to allow access to native handle functionality
294 * that is not otherwise provided.
295 */
296 native_handle_type native_handle()
297 {
298 return impl_.get_service().native_handle(impl_.get_implementation());
299 }
300
301 /// Cancel all asynchronous operations associated with the handle.
302 /**
303 * This function causes all outstanding asynchronous read or write operations
304 * to finish immediately, and the handlers for cancelled operations will be
305 * passed the boost::asio::error::operation_aborted error.
306 *
307 * @throws boost::system::system_error Thrown on failure.
308 */
309 void cancel()
310 {
311 boost::system::error_code ec;
312 impl_.get_service().cancel(impl_.get_implementation(), ec);
313 boost::asio::detail::throw_error(ec, "cancel");
314 }
315
316 /// Cancel all asynchronous operations associated with the handle.
317 /**
318 * This function causes all outstanding asynchronous read or write operations
319 * to finish immediately, and the handlers for cancelled operations will be
320 * passed the boost::asio::error::operation_aborted error.
321 *
322 * @param ec Set to indicate what error occurred, if any.
323 */
324 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
325 {
326 impl_.get_service().cancel(impl_.get_implementation(), ec);
327 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
328 }
329
330 /// Perform a blocking wait on the object handle.
331 /**
332 * This function is used to wait for the object handle to be set to the
333 * signalled state. This function blocks and does not return until the object
334 * handle has been set to the signalled state.
335 *
336 * @throws boost::system::system_error Thrown on failure.
337 */
338 void wait()
339 {
340 boost::system::error_code ec;
341 impl_.get_service().wait(impl_.get_implementation(), ec);
342 boost::asio::detail::throw_error(ec, "wait");
343 }
344
345 /// Perform a blocking wait on the object handle.
346 /**
347 * This function is used to wait for the object handle to be set to the
348 * signalled state. This function blocks and does not return until the object
349 * handle has been set to the signalled state.
350 *
351 * @param ec Set to indicate what error occurred, if any.
352 */
353 void wait(boost::system::error_code& ec)
354 {
355 impl_.get_service().wait(impl_.get_implementation(), ec);
356 }
357
358 /// Start an asynchronous wait on the object handle.
359 /**
360 * This function is be used to initiate an asynchronous wait against the
361 * object handle. It is an initiating function for an @ref
362 * asynchronous_operation, and always returns immediately.
363 *
364 * @param token The @ref completion_token that will be used to produce a
365 * completion handler, which will be called when the wait completes.
366 * Potential completion tokens include @ref use_future, @ref use_awaitable,
367 * @ref yield_context, or a function object with the correct completion
368 * signature. The function signature of the completion handler must be:
369 * @code void handler(
370 * const boost::system::error_code& error // Result of operation.
371 * ); @endcode
372 * Regardless of whether the asynchronous operation completes immediately or
373 * not, the completion handler will not be invoked from within this function.
374 * On immediate completion, invocation of the handler will be performed in a
375 * manner equivalent to using boost::asio::post().
376 *
377 * @par Completion Signature
378 * @code void(boost::system::error_code) @endcode
379 */
380 template <
381 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
382 WaitToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
383 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitToken,
384 void (boost::system::error_code))
385 async_wait(
386 BOOST_ASIO_MOVE_ARG(WaitToken) token
387 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
388 {
389 return async_initiate<WaitToken, void (boost::system::error_code)>(
390 initiate_async_wait(this), token);
391 }
392
393 private:
394 // Disallow copying and assignment.
395 basic_object_handle(const basic_object_handle&) BOOST_ASIO_DELETED;
396 basic_object_handle& operator=(const basic_object_handle&) BOOST_ASIO_DELETED;
397
398 class initiate_async_wait
399 {
400 public:
401 typedef Executor executor_type;
402
403 explicit initiate_async_wait(basic_object_handle* self)
404 : self_(self)
405 {
406 }
407
408 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
409 {
410 return self_->get_executor();
411 }
412
413 template <typename WaitHandler>
414 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const
415 {
416 // If you get an error on the following line it means that your handler
417 // does not meet the documented type requirements for a WaitHandler.
418 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
419
420 detail::non_const_lvalue<WaitHandler> handler2(handler);
421 self_->impl_.get_service().async_wait(
422 self_->impl_.get_implementation(),
423 handler2.value, self_->impl_.get_executor());
424 }
425
426 private:
427 basic_object_handle* self_;
428 };
429
430 boost::asio::detail::io_object_impl<
431 boost::asio::detail::win_object_handle_service, Executor> impl_;
432 };
433
434 } // namespace windows
435 } // namespace asio
436 } // namespace boost
437
438 #include <boost/asio/detail/pop_options.hpp>
439
440 #endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
441 // || defined(GENERATING_DOCUMENTATION)
442
443 #endif // BOOST_ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP