2 // windows/object_handle.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 // Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
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)
12 #ifndef BOOST_ASIO_WINDOWS_OBJECT_HANDLE_HPP
13 #define BOOST_ASIO_WINDOWS_OBJECT_HANDLE_HPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/detail/config.hpp>
21 #if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
22 || defined(GENERATING_DOCUMENTATION)
24 #include <boost/asio/async_result.hpp>
25 #include <boost/asio/basic_io_object.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/io_context.hpp>
31 #if defined(BOOST_ASIO_HAS_MOVE)
33 #endif // defined(BOOST_ASIO_HAS_MOVE)
35 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
36 # include <boost/asio/windows/basic_object_handle.hpp>
37 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
39 #define BOOST_ASIO_SVC_T boost::asio::detail::win_object_handle_service
41 #include <boost/asio/detail/push_options.hpp>
47 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
48 // Typedef for the typical usage of an object handle.
49 typedef basic_object_handle<> object_handle;
50 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
51 /// Provides object-oriented handle functionality.
53 * The windows::object_handle class provides asynchronous and blocking
54 * object-oriented handle functionality.
57 * @e Distinct @e objects: Safe.@n
58 * @e Shared @e objects: Unsafe.
61 : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
64 /// The type of the executor associated with the object.
65 typedef io_context::executor_type executor_type;
67 /// The native representation of a handle.
68 #if defined(GENERATING_DOCUMENTATION)
69 typedef implementation_defined native_handle_type;
71 typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
74 /// An object_handle is always the lowest layer.
75 typedef object_handle lowest_layer_type;
77 /// Construct an object_handle without opening it.
79 * This constructor creates an object handle without opening it.
81 * @param io_context The io_context object that the object handle will use to
82 * dispatch handlers for any asynchronous operations performed on the handle.
84 explicit object_handle(boost::asio::io_context& io_context)
85 : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
89 /// Construct an object_handle on an existing native handle.
91 * This constructor creates an object handle object to hold an existing native
94 * @param io_context The io_context object that the object handle will use to
95 * dispatch handlers for any asynchronous operations performed on the handle.
97 * @param native_handle The new underlying handle implementation.
99 * @throws boost::system::system_error Thrown on failure.
101 object_handle(boost::asio::io_context& io_context,
102 const native_handle_type& native_handle)
103 : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
105 boost::system::error_code ec;
106 this->get_service().assign(this->get_implementation(), native_handle, ec);
107 boost::asio::detail::throw_error(ec, "assign");
110 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
111 /// Move-construct an object_handle from another.
113 * This constructor moves an object handle from one object to another.
115 * @param other The other object_handle object from which the move will
118 * @note Following the move, the moved-from object is in the same state as if
119 * constructed using the @c object_handle(io_context&) constructor.
121 object_handle(object_handle&& other)
122 : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
126 /// Move-assign an object_handle from another.
128 * This assignment operator moves an object handle from one object to another.
130 * @param other The other object_handle object from which the move will
133 * @note Following the move, the moved-from object is in the same state as if
134 * constructed using the @c object_handle(io_context&) constructor.
136 object_handle& operator=(object_handle&& other)
138 basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
141 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
143 #if !defined(BOOST_ASIO_NO_DEPRECATED)
144 /// (Deprecated: Use get_executor().) Get the io_context associated with the
147 * This function may be used to obtain the io_context object that the I/O
148 * object uses to dispatch handlers for asynchronous operations.
150 * @return A reference to the io_context object that the I/O object will use
151 * to dispatch handlers. Ownership is not transferred to the caller.
153 boost::asio::io_context& get_io_context()
155 return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
158 /// (Deprecated: Use get_executor().) Get the io_context associated with the
161 * This function may be used to obtain the io_context object that the I/O
162 * object uses to dispatch handlers for asynchronous operations.
164 * @return A reference to the io_context object that the I/O object will use
165 * to dispatch handlers. Ownership is not transferred to the caller.
167 boost::asio::io_context& get_io_service()
169 return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
171 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
173 /// Get the executor associated with the object.
174 executor_type get_executor() BOOST_ASIO_NOEXCEPT
176 return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
179 /// Get a reference to the lowest layer.
181 * This function returns a reference to the lowest layer in a stack of
182 * layers. Since an object_handle cannot contain any further layers, it simply
183 * returns a reference to itself.
185 * @return A reference to the lowest layer in the stack of layers. Ownership
186 * is not transferred to the caller.
188 lowest_layer_type& lowest_layer()
193 /// Get a const reference to the lowest layer.
195 * This function returns a const reference to the lowest layer in a stack of
196 * layers. Since an object_handle cannot contain any further layers, it simply
197 * returns a reference to itself.
199 * @return A const reference to the lowest layer in the stack of layers.
200 * Ownership is not transferred to the caller.
202 const lowest_layer_type& lowest_layer() const
207 /// Assign an existing native handle to the handle.
209 * This function opens the handle to hold an existing native handle.
211 * @param handle A native handle.
213 * @throws boost::system::system_error Thrown on failure.
215 void assign(const native_handle_type& handle)
217 boost::system::error_code ec;
218 this->get_service().assign(this->get_implementation(), handle, ec);
219 boost::asio::detail::throw_error(ec, "assign");
222 /// Assign an existing native handle to the handle.
224 * This function opens the handle to hold an existing native handle.
226 * @param handle A native handle.
228 * @param ec Set to indicate what error occurred, if any.
230 BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
231 boost::system::error_code& ec)
233 this->get_service().assign(this->get_implementation(), handle, ec);
234 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
237 /// Determine whether the handle is open.
240 return this->get_service().is_open(this->get_implementation());
243 /// Close the handle.
245 * This function is used to close the handle. Any asynchronous read or write
246 * operations will be cancelled immediately, and will complete with the
247 * boost::asio::error::operation_aborted error.
249 * @throws boost::system::system_error Thrown on failure.
253 boost::system::error_code ec;
254 this->get_service().close(this->get_implementation(), ec);
255 boost::asio::detail::throw_error(ec, "close");
258 /// Close the handle.
260 * This function is used to close the handle. Any asynchronous read or write
261 * operations will be cancelled immediately, and will complete with the
262 * boost::asio::error::operation_aborted error.
264 * @param ec Set to indicate what error occurred, if any.
266 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
268 this->get_service().close(this->get_implementation(), ec);
269 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
272 /// Get the native handle representation.
274 * This function may be used to obtain the underlying representation of the
275 * handle. This is intended to allow access to native handle functionality
276 * that is not otherwise provided.
278 native_handle_type native_handle()
280 return this->get_service().native_handle(this->get_implementation());
283 /// Cancel all asynchronous operations associated with the handle.
285 * This function causes all outstanding asynchronous read or write operations
286 * to finish immediately, and the handlers for cancelled operations will be
287 * passed the boost::asio::error::operation_aborted error.
289 * @throws boost::system::system_error Thrown on failure.
293 boost::system::error_code ec;
294 this->get_service().cancel(this->get_implementation(), ec);
295 boost::asio::detail::throw_error(ec, "cancel");
298 /// Cancel all asynchronous operations associated with the handle.
300 * This function causes all outstanding asynchronous read or write operations
301 * to finish immediately, and the handlers for cancelled operations will be
302 * passed the boost::asio::error::operation_aborted error.
304 * @param ec Set to indicate what error occurred, if any.
306 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
308 this->get_service().cancel(this->get_implementation(), ec);
309 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
312 /// Perform a blocking wait on the object handle.
314 * This function is used to wait for the object handle to be set to the
315 * signalled state. This function blocks and does not return until the object
316 * handle has been set to the signalled state.
318 * @throws boost::system::system_error Thrown on failure.
322 boost::system::error_code ec;
323 this->get_service().wait(this->get_implementation(), ec);
324 boost::asio::detail::throw_error(ec, "wait");
327 /// Perform a blocking wait on the object handle.
329 * This function is used to wait for the object handle to be set to the
330 * signalled state. This function blocks and does not return until the object
331 * handle has been set to the signalled state.
333 * @param ec Set to indicate what error occurred, if any.
335 void wait(boost::system::error_code& ec)
337 this->get_service().wait(this->get_implementation(), ec);
340 /// Start an asynchronous wait on the object handle.
342 * This function is be used to initiate an asynchronous wait against the
343 * object handle. It always returns immediately.
345 * @param handler The handler to be called when the object handle is set to
346 * the signalled state. Copies will be made of the handler as required. The
347 * function signature of the handler must be:
348 * @code void handler(
349 * const boost::system::error_code& error // Result of operation.
351 * Regardless of whether the asynchronous operation completes immediately or
352 * not, the handler will not be invoked from within this function. Invocation
353 * of the handler will be performed in a manner equivalent to using
354 * boost::asio::io_context::post().
356 template <typename WaitHandler>
357 BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
358 void (boost::system::error_code))
359 async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
361 boost::asio::async_completion<WaitHandler,
362 void (boost::system::error_code)> init(handler);
364 this->get_service().async_wait(this->get_implementation(),
365 init.completion_handler);
367 return init.result.get();
370 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
372 } // namespace windows
376 #include <boost/asio/detail/pop_options.hpp>
378 #undef BOOST_ASIO_SVC_T
380 #endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
381 // || defined(GENERATING_DOCUMENTATION)
383 #endif // BOOST_ASIO_WINDOWS_OBJECT_HANDLE_HPP