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_SOCKET_ACCEPT_OP_HPP
0012 #define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_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/detail/bind_handler.hpp>
0023 #include <boost/asio/detail/fenced_block.hpp>
0024 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0025 #include <boost/asio/detail/handler_work.hpp>
0026 #include <boost/asio/detail/memory.hpp>
0027 #include <boost/asio/detail/operation.hpp>
0028 #include <boost/asio/detail/socket_ops.hpp>
0029 #include <boost/asio/detail/win_iocp_socket_service_base.hpp>
0030 #include <boost/asio/error.hpp>
0031
0032 #include <boost/asio/detail/push_options.hpp>
0033
0034 namespace boost {
0035 namespace asio {
0036 namespace detail {
0037
0038 template <typename Socket, typename Protocol,
0039 typename Handler, typename IoExecutor>
0040 class win_iocp_socket_accept_op : public operation
0041 {
0042 public:
0043 BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op);
0044
0045 win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service,
0046 socket_type socket, Socket& peer, const Protocol& protocol,
0047 typename Protocol::endpoint* peer_endpoint,
0048 bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex)
0049 : operation(&win_iocp_socket_accept_op::do_complete),
0050 socket_service_(socket_service),
0051 socket_(socket),
0052 peer_(peer),
0053 protocol_(protocol),
0054 peer_endpoint_(peer_endpoint),
0055 enable_connection_aborted_(enable_connection_aborted),
0056 proxy_op_(0),
0057 cancel_requested_(0),
0058 handler_(static_cast<Handler&&>(handler)),
0059 work_(handler_, io_ex)
0060 {
0061 }
0062
0063 socket_holder& new_socket()
0064 {
0065 return new_socket_;
0066 }
0067
0068 void* output_buffer()
0069 {
0070 return output_buffer_;
0071 }
0072
0073 DWORD address_length()
0074 {
0075 return sizeof(sockaddr_storage_type) + 16;
0076 }
0077
0078 void enable_cancellation(long* cancel_requested, operation* proxy_op)
0079 {
0080 cancel_requested_ = cancel_requested;
0081 proxy_op_ = proxy_op;
0082 }
0083
0084 static void do_complete(void* owner, operation* base,
0085 const boost::system::error_code& result_ec,
0086 std::size_t )
0087 {
0088 boost::system::error_code ec(result_ec);
0089
0090
0091 BOOST_ASIO_ASSUME(base != 0);
0092 win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base));
0093 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0094
0095 if (owner)
0096 {
0097 typename Protocol::endpoint peer_endpoint;
0098 std::size_t addr_len = peer_endpoint.capacity();
0099 socket_ops::complete_iocp_accept(o->socket_,
0100 o->output_buffer(), o->address_length(),
0101 peer_endpoint.data(), &addr_len,
0102 o->new_socket_.get(), ec);
0103
0104
0105
0106 if (ec == boost::asio::error::connection_aborted
0107 && !o->enable_connection_aborted_)
0108 {
0109 o->reset();
0110 if (o->proxy_op_)
0111 o->proxy_op_->reset();
0112 o->socket_service_.restart_accept_op(o->socket_,
0113 o->new_socket_, o->protocol_.family(),
0114 o->protocol_.type(), o->protocol_.protocol(),
0115 o->output_buffer(), o->address_length(),
0116 o->cancel_requested_, o->proxy_op_ ? o->proxy_op_ : o);
0117 p.v = p.p = 0;
0118 return;
0119 }
0120
0121
0122
0123 if (!ec)
0124 {
0125 o->peer_.assign(o->protocol_,
0126 typename Socket::native_handle_type(
0127 o->new_socket_.get(), peer_endpoint), ec);
0128 if (!ec)
0129 o->new_socket_.release();
0130 }
0131
0132
0133 if (o->peer_endpoint_)
0134 *o->peer_endpoint_ = peer_endpoint;
0135 }
0136
0137 BOOST_ASIO_HANDLER_COMPLETION((*o));
0138
0139
0140 handler_work<Handler, IoExecutor> w(
0141 static_cast<handler_work<Handler, IoExecutor>&&>(
0142 o->work_));
0143
0144 BOOST_ASIO_ERROR_LOCATION(ec);
0145
0146
0147
0148
0149
0150
0151
0152 detail::binder1<Handler, boost::system::error_code>
0153 handler(o->handler_, ec);
0154 p.h = boost::asio::detail::addressof(handler.handler_);
0155 p.reset();
0156
0157
0158 if (owner)
0159 {
0160 fenced_block b(fenced_block::half);
0161 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
0162 w.complete(handler, handler.handler_);
0163 BOOST_ASIO_HANDLER_INVOCATION_END;
0164 }
0165 }
0166
0167 private:
0168 win_iocp_socket_service_base& socket_service_;
0169 socket_type socket_;
0170 socket_holder new_socket_;
0171 Socket& peer_;
0172 Protocol protocol_;
0173 typename Protocol::endpoint* peer_endpoint_;
0174 unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
0175 bool enable_connection_aborted_;
0176 operation* proxy_op_;
0177 long* cancel_requested_;
0178 Handler handler_;
0179 handler_work<Handler, IoExecutor> work_;
0180 };
0181
0182 template <typename Protocol, typename PeerIoExecutor,
0183 typename Handler, typename IoExecutor>
0184 class win_iocp_socket_move_accept_op : public operation
0185 {
0186 public:
0187 BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_move_accept_op);
0188
0189 win_iocp_socket_move_accept_op(
0190 win_iocp_socket_service_base& socket_service, socket_type socket,
0191 const Protocol& protocol, const PeerIoExecutor& peer_io_ex,
0192 typename Protocol::endpoint* peer_endpoint,
0193 bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex)
0194 : operation(&win_iocp_socket_move_accept_op::do_complete),
0195 socket_service_(socket_service),
0196 socket_(socket),
0197 peer_(peer_io_ex),
0198 protocol_(protocol),
0199 peer_endpoint_(peer_endpoint),
0200 enable_connection_aborted_(enable_connection_aborted),
0201 cancel_requested_(0),
0202 proxy_op_(0),
0203 handler_(static_cast<Handler&&>(handler)),
0204 work_(handler_, io_ex)
0205 {
0206 }
0207
0208 socket_holder& new_socket()
0209 {
0210 return new_socket_;
0211 }
0212
0213 void* output_buffer()
0214 {
0215 return output_buffer_;
0216 }
0217
0218 DWORD address_length()
0219 {
0220 return sizeof(sockaddr_storage_type) + 16;
0221 }
0222
0223 void enable_cancellation(long* cancel_requested, operation* proxy_op)
0224 {
0225 cancel_requested_ = cancel_requested;
0226 proxy_op_ = proxy_op;
0227 }
0228
0229 static void do_complete(void* owner, operation* base,
0230 const boost::system::error_code& result_ec,
0231 std::size_t )
0232 {
0233 boost::system::error_code ec(result_ec);
0234
0235
0236 BOOST_ASIO_ASSUME(base != 0);
0237 win_iocp_socket_move_accept_op* o(
0238 static_cast<win_iocp_socket_move_accept_op*>(base));
0239 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0240
0241 if (owner)
0242 {
0243 typename Protocol::endpoint peer_endpoint;
0244 std::size_t addr_len = peer_endpoint.capacity();
0245 socket_ops::complete_iocp_accept(o->socket_,
0246 o->output_buffer(), o->address_length(),
0247 peer_endpoint.data(), &addr_len,
0248 o->new_socket_.get(), ec);
0249
0250
0251
0252 if (ec == boost::asio::error::connection_aborted
0253 && !o->enable_connection_aborted_)
0254 {
0255 o->reset();
0256 if (o->proxy_op_)
0257 o->proxy_op_->reset();
0258 o->socket_service_.restart_accept_op(o->socket_,
0259 o->new_socket_, o->protocol_.family(),
0260 o->protocol_.type(), o->protocol_.protocol(),
0261 o->output_buffer(), o->address_length(),
0262 o->cancel_requested_, o->proxy_op_ ? o->proxy_op_ : o);
0263 p.v = p.p = 0;
0264 return;
0265 }
0266
0267
0268
0269 if (!ec)
0270 {
0271 o->peer_.assign(o->protocol_,
0272 typename Protocol::socket::native_handle_type(
0273 o->new_socket_.get(), peer_endpoint), ec);
0274 if (!ec)
0275 o->new_socket_.release();
0276 }
0277
0278
0279 if (o->peer_endpoint_)
0280 *o->peer_endpoint_ = peer_endpoint;
0281 }
0282
0283 BOOST_ASIO_HANDLER_COMPLETION((*o));
0284
0285
0286 handler_work<Handler, IoExecutor> w(
0287 static_cast<handler_work<Handler, IoExecutor>&&>(
0288 o->work_));
0289
0290 BOOST_ASIO_ERROR_LOCATION(ec);
0291
0292
0293
0294
0295
0296
0297
0298 detail::move_binder2<Handler,
0299 boost::system::error_code, peer_socket_type>
0300 handler(0, static_cast<Handler&&>(o->handler_), ec,
0301 static_cast<peer_socket_type&&>(o->peer_));
0302 p.h = boost::asio::detail::addressof(handler.handler_);
0303 p.reset();
0304
0305
0306 if (owner)
0307 {
0308 fenced_block b(fenced_block::half);
0309 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
0310 w.complete(handler, handler.handler_);
0311 BOOST_ASIO_HANDLER_INVOCATION_END;
0312 }
0313 }
0314
0315 private:
0316 typedef typename Protocol::socket::template
0317 rebind_executor<PeerIoExecutor>::other peer_socket_type;
0318
0319 win_iocp_socket_service_base& socket_service_;
0320 socket_type socket_;
0321 socket_holder new_socket_;
0322 peer_socket_type peer_;
0323 Protocol protocol_;
0324 typename Protocol::endpoint* peer_endpoint_;
0325 unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
0326 bool enable_connection_aborted_;
0327 long* cancel_requested_;
0328 operation* proxy_op_;
0329 Handler handler_;
0330 handler_work<Handler, IoExecutor> work_;
0331 };
0332
0333 }
0334 }
0335 }
0336
0337 #include <boost/asio/detail/pop_options.hpp>
0338
0339 #endif
0340
0341 #endif