File indexing completed on 2025-01-18 09:28:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP
0012 #define BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019
0020 #if defined(BOOST_ASIO_HAS_IOCP)
0021
0022 #include <boost/asio/io_context.hpp>
0023 #include <boost/asio/query.hpp>
0024 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0025 #include <boost/asio/detail/memory.hpp>
0026 #include <boost/asio/detail/noncopyable.hpp>
0027 #include <boost/asio/detail/win_iocp_overlapped_op.hpp>
0028 #include <boost/asio/detail/win_iocp_io_context.hpp>
0029
0030 #include <boost/asio/detail/push_options.hpp>
0031
0032 namespace boost {
0033 namespace asio {
0034 namespace detail {
0035
0036
0037 class win_iocp_overlapped_ptr
0038 : private noncopyable
0039 {
0040 public:
0041
0042 win_iocp_overlapped_ptr()
0043 : ptr_(0),
0044 iocp_service_(0)
0045 {
0046 }
0047
0048
0049 template <typename Executor, typename Handler>
0050 explicit win_iocp_overlapped_ptr(const Executor& ex,
0051 Handler&& handler)
0052 : ptr_(0),
0053 iocp_service_(0)
0054 {
0055 this->reset(ex, static_cast<Handler&&>(handler));
0056 }
0057
0058
0059 ~win_iocp_overlapped_ptr()
0060 {
0061 reset();
0062 }
0063
0064
0065 void reset()
0066 {
0067 if (ptr_)
0068 {
0069 ptr_->destroy();
0070 ptr_ = 0;
0071 iocp_service_->work_finished();
0072 iocp_service_ = 0;
0073 }
0074 }
0075
0076
0077
0078 template <typename Executor, typename Handler>
0079 void reset(const Executor& ex, Handler handler)
0080 {
0081 win_iocp_io_context* iocp_service = this->get_iocp_service(ex);
0082
0083 typedef win_iocp_overlapped_op<Handler, Executor> op;
0084 typename op::ptr p = { boost::asio::detail::addressof(handler),
0085 op::ptr::allocate(handler), 0 };
0086 p.p = new (p.v) op(handler, ex);
0087
0088 BOOST_ASIO_HANDLER_CREATION((ex.context(), *p.p,
0089 "iocp_service", iocp_service, 0, "overlapped"));
0090
0091 iocp_service->work_started();
0092 reset();
0093 ptr_ = p.p;
0094 p.v = p.p = 0;
0095 iocp_service_ = iocp_service;
0096 }
0097
0098
0099 OVERLAPPED* get()
0100 {
0101 return ptr_;
0102 }
0103
0104
0105 const OVERLAPPED* get() const
0106 {
0107 return ptr_;
0108 }
0109
0110
0111 OVERLAPPED* release()
0112 {
0113 if (ptr_)
0114 iocp_service_->on_pending(ptr_);
0115
0116 OVERLAPPED* tmp = ptr_;
0117 ptr_ = 0;
0118 iocp_service_ = 0;
0119 return tmp;
0120 }
0121
0122
0123 void complete(const boost::system::error_code& ec,
0124 std::size_t bytes_transferred)
0125 {
0126 if (ptr_)
0127 {
0128 iocp_service_->on_completion(ptr_, ec,
0129 static_cast<DWORD>(bytes_transferred));
0130 ptr_ = 0;
0131 iocp_service_ = 0;
0132 }
0133 }
0134
0135 private:
0136 template <typename Executor>
0137 static win_iocp_io_context* get_iocp_service(const Executor& ex,
0138 enable_if_t<
0139 can_query<const Executor&, execution::context_t>::value
0140 >* = 0)
0141 {
0142 return &use_service<win_iocp_io_context>(
0143 boost::asio::query(ex, execution::context));
0144 }
0145
0146 template <typename Executor>
0147 static win_iocp_io_context* get_iocp_service(const Executor& ex,
0148 enable_if_t<
0149 !can_query<const Executor&, execution::context_t>::value
0150 >* = 0)
0151 {
0152 return &use_service<win_iocp_io_context>(ex.context());
0153 }
0154
0155 static win_iocp_io_context* get_iocp_service(
0156 const io_context::executor_type& ex)
0157 {
0158 return &boost::asio::query(ex, execution::context).impl_;
0159 }
0160
0161 win_iocp_operation* ptr_;
0162 win_iocp_io_context* iocp_service_;
0163 };
0164
0165 }
0166 }
0167 }
0168
0169 #include <boost/asio/detail/pop_options.hpp>
0170
0171 #endif
0172
0173 #endif