Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / asio / windows / basic_overlapped_handle.hpp
1 //
2 // windows/basic_overlapped_handle.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 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_OVERLAPPED_HANDLE_HPP
12 #define BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_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
20 #if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
21   || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
22   || defined(GENERATING_DOCUMENTATION)
23
24 #include <cstddef>
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_iocp_handle_service.hpp>
29 #include <boost/asio/error.hpp>
30 #include <boost/asio/execution_context.hpp>
31 #include <boost/asio/executor.hpp>
32
33 #if defined(BOOST_ASIO_HAS_MOVE)
34 # include <utility>
35 #endif // defined(BOOST_ASIO_HAS_MOVE)
36
37 #include <boost/asio/detail/push_options.hpp>
38
39 namespace boost {
40 namespace asio {
41 namespace windows {
42
43 /// Provides Windows handle functionality for objects that support
44 /// overlapped I/O.
45 /**
46  * The windows::overlapped_handle class provides the ability to wrap a Windows
47  * handle. The underlying object referred to by the handle must support
48  * overlapped I/O.
49  *
50  * @par Thread Safety
51  * @e Distinct @e objects: Safe.@n
52  * @e Shared @e objects: Unsafe.
53  */
54 template <typename Executor = executor>
55 class basic_overlapped_handle
56 {
57 public:
58   /// The type of the executor associated with the object.
59   typedef Executor executor_type;
60
61   /// Rebinds the handle type to another executor.
62   template <typename Executor1>
63   struct rebind_executor
64   {
65     /// The handle type when rebound to the specified executor.
66     typedef basic_overlapped_handle<Executor1> other;
67   };
68
69   /// The native representation of a handle.
70 #if defined(GENERATING_DOCUMENTATION)
71   typedef implementation_defined native_handle_type;
72 #else
73   typedef boost::asio::detail::win_iocp_handle_service::native_handle_type
74     native_handle_type;
75 #endif
76
77   /// An overlapped_handle is always the lowest layer.
78   typedef basic_overlapped_handle lowest_layer_type;
79
80   /// Construct an overlapped handle without opening it.
81   /**
82    * This constructor creates an overlapped handle without opening it.
83    *
84    * @param ex The I/O executor that the overlapped handle will use, by default,
85    * to dispatch handlers for any asynchronous operations performed on the
86    * overlapped handle.
87    */
88   explicit basic_overlapped_handle(const executor_type& ex)
89     : impl_(ex)
90   {
91   }
92
93   /// Construct an overlapped handle without opening it.
94   /**
95    * This constructor creates an overlapped handle without opening it.
96    *
97    * @param context An execution context which provides the I/O executor that
98    * the overlapped handle will use, by default, to dispatch handlers for any
99    * asynchronous operations performed on the overlapped handle.
100    */
101   template <typename ExecutionContext>
102   explicit basic_overlapped_handle(ExecutionContext& context,
103       typename enable_if<
104         is_convertible<ExecutionContext&, execution_context&>::value,
105         basic_overlapped_handle
106       >::type* = 0)
107     : impl_(context)
108   {
109   }
110
111   /// Construct an overlapped handle on an existing native handle.
112   /**
113    * This constructor creates an overlapped handle object to hold an existing
114    * native handle.
115    *
116    * @param ex The I/O executor that the overlapped handle will use, by default,
117    * to dispatch handlers for any asynchronous operations performed on the
118    * overlapped handle.
119    *
120    * @param native_handle The new underlying handle implementation.
121    *
122    * @throws boost::system::system_error Thrown on failure.
123    */
124   basic_overlapped_handle(const executor_type& ex,
125       const native_handle_type& native_handle)
126     : impl_(ex)
127   {
128     boost::system::error_code ec;
129     impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
130     boost::asio::detail::throw_error(ec, "assign");
131   }
132
133   /// Construct an overlapped handle on an existing native handle.
134   /**
135    * This constructor creates an overlapped handle object to hold an existing
136    * native handle.
137    *
138    * @param context An execution context which provides the I/O executor that
139    * the overlapped handle will use, by default, to dispatch handlers for any
140    * asynchronous operations performed on the overlapped handle.
141    *
142    * @param native_handle The new underlying handle implementation.
143    *
144    * @throws boost::system::system_error Thrown on failure.
145    */
146   template <typename ExecutionContext>
147   basic_overlapped_handle(ExecutionContext& context,
148       const native_handle_type& native_handle,
149       typename enable_if<
150         is_convertible<ExecutionContext&, execution_context&>::value
151       >::type* = 0)
152     : impl_(context)
153   {
154     boost::system::error_code ec;
155     impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
156     boost::asio::detail::throw_error(ec, "assign");
157   }
158
159 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
160   /// Move-construct an overlapped handle from another.
161   /**
162    * This constructor moves a handle from one object to another.
163    *
164    * @param other The other overlapped handle object from which the move will
165    * occur.
166    *
167    * @note Following the move, the moved-from object is in the same state as if
168    * constructed using the @c overlapped_handle(const executor_type&)
169    * constructor.
170    */
171   basic_overlapped_handle(basic_overlapped_handle&& other)
172     : impl_(std::move(other.impl_))
173   {
174   }
175
176   /// Move-assign an overlapped handle from another.
177   /**
178    * This assignment operator moves a handle from one object to another.
179    *
180    * @param other The other overlapped handle object from which the move will
181    * occur.
182    *
183    * @note Following the move, the moved-from object is in the same state as if
184    * constructed using the @c overlapped_handle(const executor_type&)
185    * constructor.
186    */
187   basic_overlapped_handle& operator=(basic_overlapped_handle&& other)
188   {
189     impl_ = std::move(other.impl_);
190     return *this;
191   }
192 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
193
194   /// Get the executor associated with the object.
195   executor_type get_executor() BOOST_ASIO_NOEXCEPT
196   {
197     return impl_.get_executor();
198   }
199
200   /// Get a reference to the lowest layer.
201   /**
202    * This function returns a reference to the lowest layer in a stack of
203    * layers. Since an overlapped_handle cannot contain any further layers, it
204    * simply returns a reference to itself.
205    *
206    * @return A reference to the lowest layer in the stack of layers. Ownership
207    * is not transferred to the caller.
208    */
209   lowest_layer_type& lowest_layer()
210   {
211     return *this;
212   }
213
214   /// Get a const reference to the lowest layer.
215   /**
216    * This function returns a const reference to the lowest layer in a stack of
217    * layers. Since an overlapped_handle cannot contain any further layers, it
218    * simply returns a reference to itself.
219    *
220    * @return A const reference to the lowest layer in the stack of layers.
221    * Ownership is not transferred to the caller.
222    */
223   const lowest_layer_type& lowest_layer() const
224   {
225     return *this;
226   }
227
228   /// Assign an existing native handle to the handle.
229   /*
230    * This function opens the handle to hold an existing native handle.
231    *
232    * @param handle A native handle.
233    *
234    * @throws boost::system::system_error Thrown on failure.
235    */
236   void assign(const native_handle_type& handle)
237   {
238     boost::system::error_code ec;
239     impl_.get_service().assign(impl_.get_implementation(), handle, ec);
240     boost::asio::detail::throw_error(ec, "assign");
241   }
242
243   /// Assign an existing native handle to the handle.
244   /*
245    * This function opens the handle to hold an existing native handle.
246    *
247    * @param handle A native handle.
248    *
249    * @param ec Set to indicate what error occurred, if any.
250    */
251   BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
252       boost::system::error_code& ec)
253   {
254     impl_.get_service().assign(impl_.get_implementation(), handle, ec);
255     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
256   }
257
258   /// Determine whether the handle is open.
259   bool is_open() const
260   {
261     return impl_.get_service().is_open(impl_.get_implementation());
262   }
263
264   /// Close the handle.
265   /**
266    * This function is used to close the handle. Any asynchronous read or write
267    * operations will be cancelled immediately, and will complete with the
268    * boost::asio::error::operation_aborted error.
269    *
270    * @throws boost::system::system_error Thrown on failure.
271    */
272   void close()
273   {
274     boost::system::error_code ec;
275     impl_.get_service().close(impl_.get_implementation(), ec);
276     boost::asio::detail::throw_error(ec, "close");
277   }
278
279   /// Close the handle.
280   /**
281    * This function is used to close the handle. Any asynchronous read or write
282    * operations will be cancelled immediately, and will complete with the
283    * boost::asio::error::operation_aborted error.
284    *
285    * @param ec Set to indicate what error occurred, if any.
286    */
287   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
288   {
289     impl_.get_service().close(impl_.get_implementation(), ec);
290     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
291   }
292
293   /// Get the native handle representation.
294   /**
295    * This function may be used to obtain the underlying representation of the
296    * handle. This is intended to allow access to native handle functionality
297    * that is not otherwise provided.
298    */
299   native_handle_type native_handle()
300   {
301     return impl_.get_service().native_handle(impl_.get_implementation());
302   }
303
304   /// Cancel all asynchronous operations associated with the handle.
305   /**
306    * This function causes all outstanding asynchronous read or write operations
307    * to finish immediately, and the handlers for cancelled operations will be
308    * passed the boost::asio::error::operation_aborted error.
309    *
310    * @throws boost::system::system_error Thrown on failure.
311    */
312   void cancel()
313   {
314     boost::system::error_code ec;
315     impl_.get_service().cancel(impl_.get_implementation(), ec);
316     boost::asio::detail::throw_error(ec, "cancel");
317   }
318
319   /// Cancel all asynchronous operations associated with the handle.
320   /**
321    * This function causes all outstanding asynchronous read or write operations
322    * to finish immediately, and the handlers for cancelled operations will be
323    * passed the boost::asio::error::operation_aborted error.
324    *
325    * @param ec Set to indicate what error occurred, if any.
326    */
327   BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
328   {
329     impl_.get_service().cancel(impl_.get_implementation(), ec);
330     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
331   }
332
333 protected:
334   /// Protected destructor to prevent deletion through this type.
335   /**
336    * This function destroys the handle, cancelling any outstanding asynchronous
337    * wait operations associated with the handle as if by calling @c cancel.
338    */
339   ~basic_overlapped_handle()
340   {
341   }
342
343   boost::asio::detail::io_object_impl<
344     boost::asio::detail::win_iocp_handle_service, Executor> impl_;
345
346 private:
347   // Disallow copying and assignment.
348   basic_overlapped_handle(const basic_overlapped_handle&) BOOST_ASIO_DELETED;
349   basic_overlapped_handle& operator=(
350       const basic_overlapped_handle&) BOOST_ASIO_DELETED;
351 };
352
353 } // namespace windows
354 } // namespace asio
355 } // namespace boost
356
357 #include <boost/asio/detail/pop_options.hpp>
358
359 #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
360        //   || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
361        //   || defined(GENERATING_DOCUMENTATION)
362
363 #endif // BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP