]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/windows/basic_object_handle.hpp
update source to Ceph Pacific 16.2.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-2020 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/async_result.hpp>
25 #include <boost/asio/detail/io_object_impl.hpp>
26 #include <boost/asio/detail/throw_error.hpp>
27 #include <boost/asio/detail/win_object_handle_service.hpp>
28 #include <boost/asio/error.hpp>
29 #include <boost/asio/execution_context.hpp>
30 #include <boost/asio/executor.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 = 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_(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 enable_if<
101 is_convertible<ExecutionContext&, execution_context&>::value,
102 basic_object_handle
103 >::type* = 0)
104 : impl_(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_(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 enable_if<
147 is_convertible<ExecutionContext&, execution_context&>::value
148 >::type* = 0)
149 : impl_(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 always returns immediately.
362 *
363 * @param handler The handler to be called when the object handle is set to
364 * the signalled state. Copies will be made of the handler as required. The
365 * function signature of the handler must be:
366 * @code void handler(
367 * const boost::system::error_code& error // Result of operation.
368 * ); @endcode
369 * Regardless of whether the asynchronous operation completes immediately or
370 * not, the handler will not be invoked from within this function. On
371 * immediate completion, invocation of the handler will be performed in a
372 * manner equivalent to using boost::asio::post().
373 */
374 template <
375 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
376 WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
377 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
378 void (boost::system::error_code))
379 async_wait(
380 BOOST_ASIO_MOVE_ARG(WaitHandler) handler
381 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
382 {
383 return async_initiate<WaitHandler, void (boost::system::error_code)>(
384 initiate_async_wait(this), handler);
385 }
386
387 private:
388 // Disallow copying and assignment.
389 basic_object_handle(const basic_object_handle&) BOOST_ASIO_DELETED;
390 basic_object_handle& operator=(const basic_object_handle&) BOOST_ASIO_DELETED;
391
392 class initiate_async_wait
393 {
394 public:
395 typedef Executor executor_type;
396
397 explicit initiate_async_wait(basic_object_handle* self)
398 : self_(self)
399 {
400 }
401
402 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
403 {
404 return self_->get_executor();
405 }
406
407 template <typename WaitHandler>
408 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const
409 {
410 // If you get an error on the following line it means that your handler
411 // does not meet the documented type requirements for a WaitHandler.
412 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
413
414 detail::non_const_lvalue<WaitHandler> handler2(handler);
415 self_->impl_.get_service().async_wait(
416 self_->impl_.get_implementation(), handler2.value,
417 self_->impl_.get_implementation_executor());
418 }
419
420 private:
421 basic_object_handle* self_;
422 };
423
424 boost::asio::detail::io_object_impl<
425 boost::asio::detail::win_object_handle_service, Executor> impl_;
426 };
427
428 } // namespace windows
429 } // namespace asio
430 } // namespace boost
431
432 #include <boost/asio/detail/pop_options.hpp>
433
434 #endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
435 // || defined(GENERATING_DOCUMENTATION)
436
437 #endif // BOOST_ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP