]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // windows/object_handle.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
11fdf7f2 | 5 | // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
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_OBJECT_HANDLE_HPP | |
13 | #define BOOST_ASIO_WINDOWS_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/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> | |
30 | ||
31 | #if defined(BOOST_ASIO_HAS_MOVE) | |
32 | # include <utility> | |
33 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
34 | ||
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) | |
38 | ||
39 | #define BOOST_ASIO_SVC_T boost::asio::detail::win_object_handle_service | |
40 | ||
41 | #include <boost/asio/detail/push_options.hpp> | |
42 | ||
43 | namespace boost { | |
44 | namespace asio { | |
45 | namespace windows { | |
46 | ||
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. | |
52 | /** | |
53 | * The windows::object_handle class provides asynchronous and blocking | |
54 | * object-oriented handle functionality. | |
55 | * | |
56 | * @par Thread Safety | |
57 | * @e Distinct @e objects: Safe.@n | |
58 | * @e Shared @e objects: Unsafe. | |
59 | */ | |
60 | class object_handle | |
61 | : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T> | |
62 | { | |
63 | public: | |
64 | /// The type of the executor associated with the object. | |
65 | typedef io_context::executor_type executor_type; | |
66 | ||
67 | /// The native representation of a handle. | |
68 | #if defined(GENERATING_DOCUMENTATION) | |
69 | typedef implementation_defined native_handle_type; | |
70 | #else | |
71 | typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type; | |
72 | #endif | |
73 | ||
74 | /// An object_handle is always the lowest layer. | |
75 | typedef 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 io_context The io_context object that the object handle will use to | |
82 | * dispatch handlers for any asynchronous operations performed on the handle. | |
83 | */ | |
84 | explicit object_handle(boost::asio::io_context& io_context) | |
85 | : basic_io_object<BOOST_ASIO_SVC_T>(io_context) | |
86 | { | |
87 | } | |
88 | ||
89 | /// Construct an object_handle on an existing native handle. | |
90 | /** | |
91 | * This constructor creates an object handle object to hold an existing native | |
92 | * handle. | |
93 | * | |
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. | |
96 | * | |
97 | * @param native_handle The new underlying handle implementation. | |
98 | * | |
99 | * @throws boost::system::system_error Thrown on failure. | |
100 | */ | |
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) | |
104 | { | |
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"); | |
108 | } | |
109 | ||
110 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
111 | /// Move-construct an object_handle from another. | |
112 | /** | |
113 | * This constructor moves an object handle from one object to another. | |
114 | * | |
115 | * @param other The other object_handle object from which the move will | |
116 | * occur. | |
117 | * | |
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. | |
120 | */ | |
121 | object_handle(object_handle&& other) | |
122 | : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other)) | |
123 | { | |
124 | } | |
125 | ||
126 | /// Move-assign an object_handle from another. | |
127 | /** | |
128 | * This assignment operator moves an object handle from one object to another. | |
129 | * | |
130 | * @param other The other object_handle object from which the move will | |
131 | * occur. | |
132 | * | |
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. | |
135 | */ | |
136 | object_handle& operator=(object_handle&& other) | |
137 | { | |
138 | basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other)); | |
139 | return *this; | |
140 | } | |
141 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
142 | ||
143 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
144 | /// (Deprecated: Use get_executor().) Get the io_context associated with the | |
145 | /// object. | |
146 | /** | |
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. | |
149 | * | |
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. | |
152 | */ | |
153 | boost::asio::io_context& get_io_context() | |
154 | { | |
155 | return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context(); | |
156 | } | |
157 | ||
158 | /// (Deprecated: Use get_executor().) Get the io_context associated with the | |
159 | /// object. | |
160 | /** | |
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. | |
163 | * | |
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. | |
166 | */ | |
167 | boost::asio::io_context& get_io_service() | |
168 | { | |
169 | return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service(); | |
170 | } | |
171 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
172 | ||
173 | /// Get the executor associated with the object. | |
174 | executor_type get_executor() BOOST_ASIO_NOEXCEPT | |
175 | { | |
176 | return basic_io_object<BOOST_ASIO_SVC_T>::get_executor(); | |
177 | } | |
178 | ||
179 | /// Get a reference to the lowest layer. | |
180 | /** | |
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. | |
184 | * | |
185 | * @return A reference to the lowest layer in the stack of layers. Ownership | |
186 | * is not transferred to the caller. | |
187 | */ | |
188 | lowest_layer_type& lowest_layer() | |
189 | { | |
190 | return *this; | |
191 | } | |
192 | ||
193 | /// Get a const reference to the lowest layer. | |
194 | /** | |
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. | |
198 | * | |
199 | * @return A const reference to the lowest layer in the stack of layers. | |
200 | * Ownership is not transferred to the caller. | |
201 | */ | |
202 | const lowest_layer_type& lowest_layer() const | |
203 | { | |
204 | return *this; | |
205 | } | |
206 | ||
207 | /// Assign an existing native handle to the handle. | |
208 | /* | |
209 | * This function opens the handle to hold an existing native handle. | |
210 | * | |
211 | * @param handle A native handle. | |
212 | * | |
213 | * @throws boost::system::system_error Thrown on failure. | |
214 | */ | |
215 | void assign(const native_handle_type& handle) | |
216 | { | |
217 | boost::system::error_code ec; | |
218 | this->get_service().assign(this->get_implementation(), handle, ec); | |
219 | boost::asio::detail::throw_error(ec, "assign"); | |
220 | } | |
221 | ||
222 | /// Assign an existing native handle to the handle. | |
223 | /* | |
224 | * This function opens the handle to hold an existing native handle. | |
225 | * | |
226 | * @param handle A native handle. | |
227 | * | |
228 | * @param ec Set to indicate what error occurred, if any. | |
229 | */ | |
230 | BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, | |
231 | boost::system::error_code& ec) | |
232 | { | |
233 | this->get_service().assign(this->get_implementation(), handle, ec); | |
234 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
235 | } | |
236 | ||
237 | /// Determine whether the handle is open. | |
238 | bool is_open() const | |
239 | { | |
240 | return this->get_service().is_open(this->get_implementation()); | |
241 | } | |
242 | ||
243 | /// Close the handle. | |
244 | /** | |
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. | |
248 | * | |
249 | * @throws boost::system::system_error Thrown on failure. | |
250 | */ | |
251 | void close() | |
252 | { | |
253 | boost::system::error_code ec; | |
254 | this->get_service().close(this->get_implementation(), ec); | |
255 | boost::asio::detail::throw_error(ec, "close"); | |
256 | } | |
257 | ||
258 | /// Close the handle. | |
259 | /** | |
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. | |
263 | * | |
264 | * @param ec Set to indicate what error occurred, if any. | |
265 | */ | |
266 | BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) | |
267 | { | |
268 | this->get_service().close(this->get_implementation(), ec); | |
269 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
270 | } | |
271 | ||
272 | /// Get the native handle representation. | |
273 | /** | |
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. | |
277 | */ | |
278 | native_handle_type native_handle() | |
279 | { | |
280 | return this->get_service().native_handle(this->get_implementation()); | |
281 | } | |
282 | ||
283 | /// Cancel all asynchronous operations associated with the handle. | |
284 | /** | |
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. | |
288 | * | |
289 | * @throws boost::system::system_error Thrown on failure. | |
290 | */ | |
291 | void cancel() | |
292 | { | |
293 | boost::system::error_code ec; | |
294 | this->get_service().cancel(this->get_implementation(), ec); | |
295 | boost::asio::detail::throw_error(ec, "cancel"); | |
296 | } | |
297 | ||
298 | /// Cancel all asynchronous operations associated with the handle. | |
299 | /** | |
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. | |
303 | * | |
304 | * @param ec Set to indicate what error occurred, if any. | |
305 | */ | |
306 | BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) | |
307 | { | |
308 | this->get_service().cancel(this->get_implementation(), ec); | |
309 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); | |
310 | } | |
311 | ||
312 | /// Perform a blocking wait on the object handle. | |
313 | /** | |
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. | |
317 | * | |
318 | * @throws boost::system::system_error Thrown on failure. | |
319 | */ | |
320 | void wait() | |
321 | { | |
322 | boost::system::error_code ec; | |
323 | this->get_service().wait(this->get_implementation(), ec); | |
324 | boost::asio::detail::throw_error(ec, "wait"); | |
325 | } | |
326 | ||
327 | /// Perform a blocking wait on the object handle. | |
328 | /** | |
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. | |
332 | * | |
333 | * @param ec Set to indicate what error occurred, if any. | |
334 | */ | |
335 | void wait(boost::system::error_code& ec) | |
336 | { | |
337 | this->get_service().wait(this->get_implementation(), ec); | |
338 | } | |
339 | ||
340 | /// Start an asynchronous wait on the object handle. | |
341 | /** | |
342 | * This function is be used to initiate an asynchronous wait against the | |
343 | * object handle. It always returns immediately. | |
344 | * | |
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. | |
350 | * ); @endcode | |
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(). | |
355 | */ | |
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) | |
360 | { | |
361 | boost::asio::async_completion<WaitHandler, | |
362 | void (boost::system::error_code)> init(handler); | |
363 | ||
364 | this->get_service().async_wait(this->get_implementation(), | |
365 | init.completion_handler); | |
366 | ||
367 | return init.result.get(); | |
368 | } | |
369 | }; | |
370 | #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) | |
371 | ||
372 | } // namespace windows | |
373 | } // namespace asio | |
374 | } // namespace boost | |
375 | ||
376 | #include <boost/asio/detail/pop_options.hpp> | |
377 | ||
378 | #undef BOOST_ASIO_SVC_T | |
379 | ||
380 | #endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) | |
381 | // || defined(GENERATING_DOCUMENTATION) | |
382 | ||
383 | #endif // BOOST_ASIO_WINDOWS_OBJECT_HANDLE_HPP |