Back to home page

EIC code displayed by LXR

 
 

    


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