1//
2// windows/basic_handle.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 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_HANDLE_HPP
12#define BOOST_ASIO_WINDOWS_BASIC_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(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
23 || defined(GENERATING_DOCUMENTATION)
24
25#include <boost/asio/basic_io_object.hpp>
26#include <boost/asio/detail/throw_error.hpp>
27#include <boost/asio/error.hpp>
28
29#include <boost/asio/detail/push_options.hpp>
30
31namespace boost {
32namespace asio {
33namespace windows {
34
35/// Provides Windows handle functionality.
36/**
37 * The windows::basic_handle class template provides the ability to wrap a
38 * Windows handle.
39 *
40 * @par Thread Safety
41 * @e Distinct @e objects: Safe.@n
42 * @e Shared @e objects: Unsafe.
43 */
44template <typename HandleService>
45class basic_handle
46 : public basic_io_object<HandleService>
47{
48public:
49 /// (Deprecated: Use native_handle_type.) The native representation of a
50 /// handle.
51 typedef typename HandleService::native_handle_type native_type;
52
53 /// The native representation of a handle.
54 typedef typename HandleService::native_handle_type native_handle_type;
55
56 /// A basic_handle is always the lowest layer.
57 typedef basic_handle<HandleService> lowest_layer_type;
58
59 /// Construct a basic_handle without opening it.
60 /**
61 * This constructor creates a handle without opening it.
62 *
63 * @param io_service The io_service object that the handle will use to
64 * dispatch handlers for any asynchronous operations performed on the handle.
65 */
66 explicit basic_handle(boost::asio::io_service& io_service)
67 : basic_io_object<HandleService>(io_service)
68 {
69 }
70
71 /// Construct a basic_handle on an existing native handle.
72 /**
73 * This constructor creates a handle object to hold an existing native handle.
74 *
75 * @param io_service The io_service object that the handle will use to
76 * dispatch handlers for any asynchronous operations performed on the handle.
77 *
78 * @param handle A native handle.
79 *
80 * @throws boost::system::system_error Thrown on failure.
81 */
82 basic_handle(boost::asio::io_service& io_service,
83 const native_handle_type& handle)
84 : basic_io_object<HandleService>(io_service)
85 {
86 boost::system::error_code ec;
87 this->get_service().assign(this->get_implementation(), handle, ec);
88 boost::asio::detail::throw_error(ec, "assign");
89 }
90
91#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
92 /// Move-construct a basic_handle from another.
93 /**
94 * This constructor moves a handle from one object to another.
95 *
96 * @param other The other basic_handle object from which the move will occur.
97 *
98 * @note Following the move, the moved-from object is in the same state as if
99 * constructed using the @c basic_handle(io_service&) constructor.
100 */
101 basic_handle(basic_handle&& other)
102 : basic_io_object<HandleService>(
103 BOOST_ASIO_MOVE_CAST(basic_handle)(other))
104 {
105 }
106
107 /// Move-assign a basic_handle from another.
108 /**
109 * This assignment operator moves a handle from one object to another.
110 *
111 * @param other The other basic_handle object from which the move will occur.
112 *
113 * @note Following the move, the moved-from object is in the same state as if
114 * constructed using the @c basic_handle(io_service&) constructor.
115 */
116 basic_handle& operator=(basic_handle&& other)
117 {
118 basic_io_object<HandleService>::operator=(
119 BOOST_ASIO_MOVE_CAST(basic_handle)(other));
120 return *this;
121 }
122#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
123
124 /// Get a reference to the lowest layer.
125 /**
126 * This function returns a reference to the lowest layer in a stack of
127 * layers. Since a basic_handle cannot contain any further layers, it simply
128 * returns a reference to itself.
129 *
130 * @return A reference to the lowest layer in the stack of layers. Ownership
131 * is not transferred to the caller.
132 */
133 lowest_layer_type& lowest_layer()
134 {
135 return *this;
136 }
137
138 /// Get a const reference to the lowest layer.
139 /**
140 * This function returns a const reference to the lowest layer in a stack of
141 * layers. Since a basic_handle cannot contain any further layers, it simply
142 * returns a reference to itself.
143 *
144 * @return A const reference to the lowest layer in the stack of layers.
145 * Ownership is not transferred to the caller.
146 */
147 const lowest_layer_type& lowest_layer() const
148 {
149 return *this;
150 }
151
152 /// Assign an existing native handle to the handle.
153 /*
154 * This function opens the handle to hold an existing native handle.
155 *
156 * @param handle A native handle.
157 *
158 * @throws boost::system::system_error Thrown on failure.
159 */
160 void assign(const native_handle_type& handle)
161 {
162 boost::system::error_code ec;
163 this->get_service().assign(this->get_implementation(), handle, ec);
164 boost::asio::detail::throw_error(ec, "assign");
165 }
166
167 /// Assign an existing native handle to the handle.
168 /*
169 * This function opens the handle to hold an existing native handle.
170 *
171 * @param handle A native handle.
172 *
173 * @param ec Set to indicate what error occurred, if any.
174 */
175 boost::system::error_code assign(const native_handle_type& handle,
176 boost::system::error_code& ec)
177 {
178 return this->get_service().assign(this->get_implementation(), handle, ec);
179 }
180
181 /// Determine whether the handle is open.
182 bool is_open() const
183 {
184 return this->get_service().is_open(this->get_implementation());
185 }
186
187 /// Close the handle.
188 /**
189 * This function is used to close the handle. Any asynchronous read or write
190 * operations will be cancelled immediately, and will complete with the
191 * boost::asio::error::operation_aborted error.
192 *
193 * @throws boost::system::system_error Thrown on failure.
194 */
195 void close()
196 {
197 boost::system::error_code ec;
198 this->get_service().close(this->get_implementation(), ec);
199 boost::asio::detail::throw_error(ec, "close");
200 }
201
202 /// Close the handle.
203 /**
204 * This function is used to close the handle. Any asynchronous read or write
205 * operations will be cancelled immediately, and will complete with the
206 * boost::asio::error::operation_aborted error.
207 *
208 * @param ec Set to indicate what error occurred, if any.
209 */
210 boost::system::error_code close(boost::system::error_code& ec)
211 {
212 return this->get_service().close(this->get_implementation(), ec);
213 }
214
215 /// (Deprecated: Use native_handle().) Get the native handle representation.
216 /**
217 * This function may be used to obtain the underlying representation of the
218 * handle. This is intended to allow access to native handle functionality
219 * that is not otherwise provided.
220 */
221 native_type native()
222 {
223 return this->get_service().native_handle(this->get_implementation());
224 }
225
226 /// Get the native handle representation.
227 /**
228 * This function may be used to obtain the underlying representation of the
229 * handle. This is intended to allow access to native handle functionality
230 * that is not otherwise provided.
231 */
232 native_handle_type native_handle()
233 {
234 return this->get_service().native_handle(this->get_implementation());
235 }
236
237 /// Cancel all asynchronous operations associated with the handle.
238 /**
239 * This function causes all outstanding asynchronous read or write operations
240 * to finish immediately, and the handlers for cancelled operations will be
241 * passed the boost::asio::error::operation_aborted error.
242 *
243 * @throws boost::system::system_error Thrown on failure.
244 */
245 void cancel()
246 {
247 boost::system::error_code ec;
248 this->get_service().cancel(this->get_implementation(), ec);
249 boost::asio::detail::throw_error(ec, "cancel");
250 }
251
252 /// Cancel all asynchronous operations associated with the handle.
253 /**
254 * This function causes all outstanding asynchronous read or write operations
255 * to finish immediately, and the handlers for cancelled operations will be
256 * passed the boost::asio::error::operation_aborted error.
257 *
258 * @param ec Set to indicate what error occurred, if any.
259 */
260 boost::system::error_code cancel(boost::system::error_code& ec)
261 {
262 return this->get_service().cancel(this->get_implementation(), ec);
263 }
264
265protected:
266 /// Protected destructor to prevent deletion through this type.
267 ~basic_handle()
268 {
269 }
270};
271
272} // namespace windows
273} // namespace asio
274} // namespace boost
275
276#include <boost/asio/detail/pop_options.hpp>
277
278#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
279 // || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
280 // || defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
281 // || defined(GENERATING_DOCUMENTATION)
282
283#endif // BOOST_ASIO_WINDOWS_BASIC_HANDLE_HPP
284