|
||||
File indexing completed on 2025-01-18 09:29:03
0001 // 0002 // windows/basic_overlapped_handle.hpp 0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP 0012 #define BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 0020 #if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ 0021 || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \ 0022 || defined(GENERATING_DOCUMENTATION) 0023 0024 #include <cstddef> 0025 #include <utility> 0026 #include <boost/asio/any_io_executor.hpp> 0027 #include <boost/asio/async_result.hpp> 0028 #include <boost/asio/detail/io_object_impl.hpp> 0029 #include <boost/asio/detail/throw_error.hpp> 0030 #include <boost/asio/detail/win_iocp_handle_service.hpp> 0031 #include <boost/asio/error.hpp> 0032 #include <boost/asio/execution_context.hpp> 0033 0034 #include <boost/asio/detail/push_options.hpp> 0035 0036 namespace boost { 0037 namespace asio { 0038 namespace windows { 0039 0040 /// Provides Windows handle functionality for objects that support 0041 /// overlapped I/O. 0042 /** 0043 * The windows::overlapped_handle class provides the ability to wrap a Windows 0044 * handle. The underlying object referred to by the handle must support 0045 * overlapped I/O. 0046 * 0047 * @par Thread Safety 0048 * @e Distinct @e objects: Safe.@n 0049 * @e Shared @e objects: Unsafe. 0050 */ 0051 template <typename Executor = any_io_executor> 0052 class basic_overlapped_handle 0053 { 0054 public: 0055 /// The type of the executor associated with the object. 0056 typedef Executor executor_type; 0057 0058 /// Rebinds the handle type to another executor. 0059 template <typename Executor1> 0060 struct rebind_executor 0061 { 0062 /// The handle type when rebound to the specified executor. 0063 typedef basic_overlapped_handle<Executor1> other; 0064 }; 0065 0066 /// The native representation of a handle. 0067 #if defined(GENERATING_DOCUMENTATION) 0068 typedef implementation_defined native_handle_type; 0069 #else 0070 typedef boost::asio::detail::win_iocp_handle_service::native_handle_type 0071 native_handle_type; 0072 #endif 0073 0074 /// An overlapped_handle is always the lowest layer. 0075 typedef basic_overlapped_handle lowest_layer_type; 0076 0077 /// Construct an overlapped handle without opening it. 0078 /** 0079 * This constructor creates an overlapped handle without opening it. 0080 * 0081 * @param ex The I/O executor that the overlapped handle will use, by default, 0082 * to dispatch handlers for any asynchronous operations performed on the 0083 * overlapped handle. 0084 */ 0085 explicit basic_overlapped_handle(const executor_type& ex) 0086 : impl_(0, ex) 0087 { 0088 } 0089 0090 /// Construct an overlapped handle without opening it. 0091 /** 0092 * This constructor creates an overlapped handle without opening it. 0093 * 0094 * @param context An execution context which provides the I/O executor that 0095 * the overlapped handle will use, by default, to dispatch handlers for any 0096 * asynchronous operations performed on the overlapped handle. 0097 */ 0098 template <typename ExecutionContext> 0099 explicit basic_overlapped_handle(ExecutionContext& context, 0100 constraint_t< 0101 is_convertible<ExecutionContext&, execution_context&>::value, 0102 defaulted_constraint 0103 > = defaulted_constraint()) 0104 : impl_(0, 0, context) 0105 { 0106 } 0107 0108 /// Construct an overlapped handle on an existing native handle. 0109 /** 0110 * This constructor creates an overlapped handle object to hold an existing 0111 * native handle. 0112 * 0113 * @param ex The I/O executor that the overlapped handle will use, by default, 0114 * to dispatch handlers for any asynchronous operations performed on the 0115 * overlapped handle. 0116 * 0117 * @param native_handle The new underlying handle implementation. 0118 * 0119 * @throws boost::system::system_error Thrown on failure. 0120 */ 0121 basic_overlapped_handle(const executor_type& ex, 0122 const native_handle_type& native_handle) 0123 : impl_(0, ex) 0124 { 0125 boost::system::error_code ec; 0126 impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); 0127 boost::asio::detail::throw_error(ec, "assign"); 0128 } 0129 0130 /// Construct an overlapped handle on an existing native handle. 0131 /** 0132 * This constructor creates an overlapped handle object to hold an existing 0133 * native handle. 0134 * 0135 * @param context An execution context which provides the I/O executor that 0136 * the overlapped handle will use, by default, to dispatch handlers for any 0137 * asynchronous operations performed on the overlapped handle. 0138 * 0139 * @param native_handle The new underlying handle implementation. 0140 * 0141 * @throws boost::system::system_error Thrown on failure. 0142 */ 0143 template <typename ExecutionContext> 0144 basic_overlapped_handle(ExecutionContext& context, 0145 const native_handle_type& native_handle, 0146 constraint_t< 0147 is_convertible<ExecutionContext&, execution_context&>::value 0148 > = 0) 0149 : impl_(0, 0, context) 0150 { 0151 boost::system::error_code ec; 0152 impl_.get_service().assign(impl_.get_implementation(), native_handle, ec); 0153 boost::asio::detail::throw_error(ec, "assign"); 0154 } 0155 0156 /// Move-construct an overlapped handle from another. 0157 /** 0158 * This constructor moves a handle from one object to another. 0159 * 0160 * @param other The other overlapped handle object from which the move will 0161 * occur. 0162 * 0163 * @note Following the move, the moved-from object is in the same state as if 0164 * constructed using the @c overlapped_handle(const executor_type&) 0165 * constructor. 0166 */ 0167 basic_overlapped_handle(basic_overlapped_handle&& other) 0168 : impl_(std::move(other.impl_)) 0169 { 0170 } 0171 0172 /// Move-assign an overlapped handle from another. 0173 /** 0174 * This assignment operator moves a handle from one object to another. 0175 * 0176 * @param other The other overlapped handle object from which the move will 0177 * occur. 0178 * 0179 * @note Following the move, the moved-from object is in the same state as if 0180 * constructed using the @c overlapped_handle(const executor_type&) 0181 * constructor. 0182 */ 0183 basic_overlapped_handle& operator=(basic_overlapped_handle&& other) 0184 { 0185 impl_ = std::move(other.impl_); 0186 return *this; 0187 } 0188 0189 // All overlapped handles have access to each other's implementations. 0190 template <typename Executor1> 0191 friend class basic_overlapped_handle; 0192 0193 /// Move-construct an overlapped handle from a handle of another executor 0194 /// type. 0195 /** 0196 * This constructor moves a handle from one object to another. 0197 * 0198 * @param other The other overlapped handle object from which the move will 0199 * occur. 0200 * 0201 * @note Following the move, the moved-from object is in the same state as if 0202 * constructed using the @c overlapped_handle(const executor_type&) 0203 * constructor. 0204 */ 0205 template<typename Executor1> 0206 basic_overlapped_handle(basic_overlapped_handle<Executor1>&& other, 0207 constraint_t< 0208 is_convertible<Executor1, Executor>::value, 0209 defaulted_constraint 0210 > = defaulted_constraint()) 0211 : impl_(std::move(other.impl_)) 0212 { 0213 } 0214 0215 /// Move-assign an overlapped handle from a handle of another executor type. 0216 /** 0217 * This assignment operator moves a handle from one object to another. 0218 * 0219 * @param other The other overlapped handle object from which the move will 0220 * occur. 0221 * 0222 * @note Following the move, the moved-from object is in the same state as if 0223 * constructed using the @c overlapped_handle(const executor_type&) 0224 * constructor. 0225 */ 0226 template<typename Executor1> 0227 constraint_t< 0228 is_convertible<Executor1, Executor>::value, 0229 basic_overlapped_handle& 0230 > operator=(basic_overlapped_handle<Executor1>&& other) 0231 { 0232 impl_ = std::move(other.impl_); 0233 return *this; 0234 } 0235 0236 /// Get the executor associated with the object. 0237 const executor_type& get_executor() noexcept 0238 { 0239 return impl_.get_executor(); 0240 } 0241 0242 /// Get a reference to the lowest layer. 0243 /** 0244 * This function returns a reference to the lowest layer in a stack of 0245 * layers. Since an overlapped_handle cannot contain any further layers, it 0246 * simply returns a reference to itself. 0247 * 0248 * @return A reference to the lowest layer in the stack of layers. Ownership 0249 * is not transferred to the caller. 0250 */ 0251 lowest_layer_type& lowest_layer() 0252 { 0253 return *this; 0254 } 0255 0256 /// Get a const reference to the lowest layer. 0257 /** 0258 * This function returns a const reference to the lowest layer in a stack of 0259 * layers. Since an overlapped_handle cannot contain any further layers, it 0260 * simply returns a reference to itself. 0261 * 0262 * @return A const reference to the lowest layer in the stack of layers. 0263 * Ownership is not transferred to the caller. 0264 */ 0265 const lowest_layer_type& lowest_layer() const 0266 { 0267 return *this; 0268 } 0269 0270 /// Assign an existing native handle to the handle. 0271 /* 0272 * This function opens the handle to hold an existing native handle. 0273 * 0274 * @param handle A native handle. 0275 * 0276 * @throws boost::system::system_error Thrown on failure. 0277 */ 0278 void assign(const native_handle_type& handle) 0279 { 0280 boost::system::error_code ec; 0281 impl_.get_service().assign(impl_.get_implementation(), handle, ec); 0282 boost::asio::detail::throw_error(ec, "assign"); 0283 } 0284 0285 /// Assign an existing native handle to the handle. 0286 /* 0287 * This function opens the handle to hold an existing native handle. 0288 * 0289 * @param handle A native handle. 0290 * 0291 * @param ec Set to indicate what error occurred, if any. 0292 */ 0293 BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, 0294 boost::system::error_code& ec) 0295 { 0296 impl_.get_service().assign(impl_.get_implementation(), handle, ec); 0297 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0298 } 0299 0300 /// Determine whether the handle is open. 0301 bool is_open() const 0302 { 0303 return impl_.get_service().is_open(impl_.get_implementation()); 0304 } 0305 0306 /// Close the handle. 0307 /** 0308 * This function is used to close the handle. Any asynchronous read or write 0309 * operations will be cancelled immediately, and will complete with the 0310 * boost::asio::error::operation_aborted error. 0311 * 0312 * @throws boost::system::system_error Thrown on failure. 0313 */ 0314 void close() 0315 { 0316 boost::system::error_code ec; 0317 impl_.get_service().close(impl_.get_implementation(), ec); 0318 boost::asio::detail::throw_error(ec, "close"); 0319 } 0320 0321 /// Close the handle. 0322 /** 0323 * This function is used to close the handle. Any asynchronous read or write 0324 * operations will be cancelled immediately, and will complete with the 0325 * boost::asio::error::operation_aborted error. 0326 * 0327 * @param ec Set to indicate what error occurred, if any. 0328 */ 0329 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) 0330 { 0331 impl_.get_service().close(impl_.get_implementation(), ec); 0332 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0333 } 0334 0335 /// Release ownership of the underlying native handle. 0336 /** 0337 * This function causes all outstanding asynchronous operations to finish 0338 * immediately, and the handlers for cancelled operations will be passed the 0339 * boost::asio::error::operation_aborted error. Ownership of the native handle 0340 * is then transferred to the caller. 0341 * 0342 * @throws boost::system::system_error Thrown on failure. 0343 * 0344 * @note This function is unsupported on Windows versions prior to Windows 0345 * 8.1, and will fail with boost::asio::error::operation_not_supported on 0346 * these platforms. 0347 */ 0348 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 0349 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 0350 __declspec(deprecated("This function always fails with " 0351 "operation_not_supported when used on Windows versions " 0352 "prior to Windows 8.1.")) 0353 #endif 0354 native_handle_type release() 0355 { 0356 boost::system::error_code ec; 0357 native_handle_type s = impl_.get_service().release( 0358 impl_.get_implementation(), ec); 0359 boost::asio::detail::throw_error(ec, "release"); 0360 return s; 0361 } 0362 0363 /// Release ownership of the underlying native handle. 0364 /** 0365 * This function causes all outstanding asynchronous operations to finish 0366 * immediately, and the handlers for cancelled operations will be passed the 0367 * boost::asio::error::operation_aborted error. Ownership of the native handle 0368 * is then transferred to the caller. 0369 * 0370 * @param ec Set to indicate what error occurred, if any. 0371 * 0372 * @note This function is unsupported on Windows versions prior to Windows 0373 * 8.1, and will fail with boost::asio::error::operation_not_supported on 0374 * these platforms. 0375 */ 0376 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 0377 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 0378 __declspec(deprecated("This function always fails with " 0379 "operation_not_supported when used on Windows versions " 0380 "prior to Windows 8.1.")) 0381 #endif 0382 native_handle_type release(boost::system::error_code& ec) 0383 { 0384 return impl_.get_service().release(impl_.get_implementation(), ec); 0385 } 0386 0387 /// Get the native handle representation. 0388 /** 0389 * This function may be used to obtain the underlying representation of the 0390 * handle. This is intended to allow access to native handle functionality 0391 * that is not otherwise provided. 0392 */ 0393 native_handle_type native_handle() 0394 { 0395 return impl_.get_service().native_handle(impl_.get_implementation()); 0396 } 0397 0398 /// Cancel all asynchronous operations associated with the handle. 0399 /** 0400 * This function causes all outstanding asynchronous read or write operations 0401 * to finish immediately, and the handlers for cancelled operations will be 0402 * passed the boost::asio::error::operation_aborted error. 0403 * 0404 * @throws boost::system::system_error Thrown on failure. 0405 */ 0406 void cancel() 0407 { 0408 boost::system::error_code ec; 0409 impl_.get_service().cancel(impl_.get_implementation(), ec); 0410 boost::asio::detail::throw_error(ec, "cancel"); 0411 } 0412 0413 /// Cancel all asynchronous operations associated with the handle. 0414 /** 0415 * This function causes all outstanding asynchronous read or write operations 0416 * to finish immediately, and the handlers for cancelled operations will be 0417 * passed the boost::asio::error::operation_aborted error. 0418 * 0419 * @param ec Set to indicate what error occurred, if any. 0420 */ 0421 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) 0422 { 0423 impl_.get_service().cancel(impl_.get_implementation(), ec); 0424 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 0425 } 0426 0427 protected: 0428 /// Protected destructor to prevent deletion through this type. 0429 /** 0430 * This function destroys the handle, cancelling any outstanding asynchronous 0431 * wait operations associated with the handle as if by calling @c cancel. 0432 */ 0433 ~basic_overlapped_handle() 0434 { 0435 } 0436 0437 boost::asio::detail::io_object_impl< 0438 boost::asio::detail::win_iocp_handle_service, Executor> impl_; 0439 0440 private: 0441 // Disallow copying and assignment. 0442 basic_overlapped_handle(const basic_overlapped_handle&) = delete; 0443 basic_overlapped_handle& operator=( 0444 const basic_overlapped_handle&) = delete; 0445 }; 0446 0447 } // namespace windows 0448 } // namespace asio 0449 } // namespace boost 0450 0451 #include <boost/asio/detail/pop_options.hpp> 0452 0453 #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) 0454 // || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) 0455 // || defined(GENERATING_DOCUMENTATION) 0456 0457 #endif // BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |