diff options
Diffstat (limited to 'boost/asio/detail/win_iocp_socket_service.hpp')
-rw-r--r-- | boost/asio/detail/win_iocp_socket_service.hpp | 135 |
1 files changed, 104 insertions, 31 deletions
diff --git a/boost/asio/detail/win_iocp_socket_service.hpp b/boost/asio/detail/win_iocp_socket_service.hpp index 179798c8d9..ed1cd1edd5 100644 --- a/boost/asio/detail/win_iocp_socket_service.hpp +++ b/boost/asio/detail/win_iocp_socket_service.hpp @@ -21,22 +21,22 @@ #include <cstring> #include <boost/asio/error.hpp> -#include <boost/asio/io_service.hpp> +#include <boost/asio/io_context.hpp> #include <boost/asio/socket_base.hpp> -#include <boost/asio/detail/addressof.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/buffer_sequence_adapter.hpp> #include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/memory.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/operation.hpp> -#include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/reactor_op.hpp> +#include <boost/asio/detail/select_reactor.hpp> #include <boost/asio/detail/socket_holder.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/socket_types.hpp> -#include <boost/asio/detail/win_iocp_io_service.hpp> +#include <boost/asio/detail/win_iocp_io_context.hpp> #include <boost/asio/detail/win_iocp_null_buffers_op.hpp> #include <boost/asio/detail/win_iocp_socket_accept_op.hpp> #include <boost/asio/detail/win_iocp_socket_connect_op.hpp> @@ -51,7 +51,9 @@ namespace asio { namespace detail { template <typename Protocol> -class win_iocp_socket_service : public win_iocp_socket_service_base +class win_iocp_socket_service : + public service_base<win_iocp_socket_service<Protocol> >, + public win_iocp_socket_service_base { public: // The protocol type. @@ -128,11 +130,18 @@ public: }; // Constructor. - win_iocp_socket_service(boost::asio::io_service& io_service) - : win_iocp_socket_service_base(io_service) + win_iocp_socket_service(boost::asio::io_context& io_context) + : service_base<win_iocp_socket_service<Protocol> >(io_context), + win_iocp_socket_service_base(io_context) { } + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + this->base_shutdown(); + } + // Move-construct a new socket implementation. void move_construct(implementation_type& impl, implementation_type& other_impl) @@ -279,6 +288,14 @@ public: return endpoint; } + // Disable sends or receives on the socket. + boost::system::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + // Send a datagram to the specified endpoint. Returns the number of bytes // sent. template <typename ConstBufferSequence> @@ -300,7 +317,7 @@ public: boost::system::error_code& ec) { // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); + socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); return 0; } @@ -315,11 +332,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, buffers, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send_to")); buffer_sequence_adapter<boost::asio::const_buffer, ConstBufferSequence> bufs(buffers); @@ -338,14 +355,13 @@ public: // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op<Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send_to(null_buffers)")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_send_to(null_buffers)")); - start_reactor_op(impl, reactor::write_op, p.p); + start_reactor_op(impl, select_reactor::write_op, p.p); p.v = p.p = 0; } @@ -377,7 +393,7 @@ public: socket_base::message_flags, boost::system::error_code& ec) { // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); + socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); @@ -397,11 +413,11 @@ public: typedef win_iocp_socket_recvfrom_op< MutableBufferSequence, endpoint_type, Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive_from")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive_from")); buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence> bufs(buffers); @@ -420,12 +436,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef win_iocp_null_buffers_op<Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.cancel_token_, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_from(null_buffers)")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_receive_from(null_buffers)")); // Reset endpoint since it can be given no sensible value at this time. sender_endpoint = endpoint_type(); @@ -456,13 +471,42 @@ public: { if (peer_endpoint) peer_endpoint->resize(addr_len); - if (!peer.assign(impl.protocol_, new_socket.get(), ec)) + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) new_socket.release(); } return ec; } +#if defined(BOOST_ASIO_HAS_MOVE) + // Accept a new connection. + typename Protocol::socket accept(implementation_type& impl, + io_context* peer_io_context, endpoint_type* peer_endpoint, + boost::system::error_code& ec) + { + typename Protocol::socket peer( + peer_io_context ? *peer_io_context : io_context_); + + std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; + socket_holder new_socket(socket_ops::sync_accept(impl.socket_, + impl.state_, peer_endpoint ? peer_endpoint->data() : 0, + peer_endpoint ? &addr_len : 0, ec)); + + // On success, assign new connection to peer socket object. + if (new_socket.get() != invalid_socket) + { + if (peer_endpoint) + peer_endpoint->resize(addr_len); + peer.assign(impl.protocol_, new_socket.get(), ec); + if (!ec) + new_socket.release(); + } + + return peer; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. template <typename Socket, typename Handler> @@ -472,14 +516,14 @@ public: // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_accept_op<Socket, protocol_type, Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; bool enable_connection_aborted = (impl.state_ & socket_ops::enable_connection_aborted) != 0; p.p = new (p.v) op(*this, impl.socket_, peer, impl.protocol_, peer_endpoint, enable_connection_aborted, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_accept")); start_accept_op(impl, peer.is_open(), p.p->new_socket(), impl.protocol_.family(), impl.protocol_.type(), @@ -488,6 +532,35 @@ public: p.v = p.p = 0; } +#if defined(BOOST_ASIO_HAS_MOVE) + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template <typename Handler> + void async_accept(implementation_type& impl, + boost::asio::io_context* peer_io_context, + endpoint_type* peer_endpoint, Handler& handler) + { + // Allocate and construct an operation to wrap the handler. + typedef win_iocp_socket_move_accept_op<protocol_type, Handler> op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + bool enable_connection_aborted = + (impl.state_ & socket_ops::enable_connection_aborted) != 0; + p.p = new (p.v) op(*this, impl.socket_, impl.protocol_, + peer_io_context ? *peer_io_context : io_context_, + peer_endpoint, enable_connection_aborted, handler); + + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_accept")); + + start_accept_op(impl, false, p.p->new_socket(), + impl.protocol_.family(), impl.protocol_.type(), + impl.protocol_.protocol(), p.p->output_buffer(), + p.p->address_length(), p.p); + p.v = p.p = 0; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + // Connect the socket to the specified endpoint. boost::system::error_code connect(implementation_type& impl, const endpoint_type& peer_endpoint, boost::system::error_code& ec) @@ -505,11 +578,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef win_iocp_socket_connect_op<Handler> op; typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; + op::ptr::allocate(handler), 0 }; p.p = new (p.v) op(impl.socket_, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); + BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket", + &impl, impl.socket_, "async_connect")); start_connect_op(impl, impl.protocol_.family(), impl.protocol_.type(), peer_endpoint.data(), static_cast<int>(peer_endpoint.size()), p.p); |