diff options
Diffstat (limited to 'boost/asio/detail/reactive_socket_service_base.hpp')
-rw-r--r-- | boost/asio/detail/reactive_socket_service_base.hpp | 129 |
1 files changed, 95 insertions, 34 deletions
diff --git a/boost/asio/detail/reactive_socket_service_base.hpp b/boost/asio/detail/reactive_socket_service_base.hpp index fb2aa5d028..17c694a3cd 100644 --- a/boost/asio/detail/reactive_socket_service_base.hpp +++ b/boost/asio/detail/reactive_socket_service_base.hpp @@ -22,14 +22,15 @@ #include <boost/asio/buffer.hpp> #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/buffer_sequence_adapter.hpp> +#include <boost/asio/detail/memory.hpp> #include <boost/asio/detail/reactive_null_buffers_op.hpp> #include <boost/asio/detail/reactive_socket_recv_op.hpp> #include <boost/asio/detail/reactive_socket_recvmsg_op.hpp> #include <boost/asio/detail/reactive_socket_send_op.hpp> +#include <boost/asio/detail/reactive_wait_op.hpp> #include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/reactor_op.hpp> #include <boost/asio/detail/socket_holder.hpp> @@ -63,10 +64,10 @@ public: // Constructor. BOOST_ASIO_DECL reactive_socket_service_base( - boost::asio::io_service& io_service); + boost::asio::io_context& io_context); // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void shutdown_service(); + BOOST_ASIO_DECL void base_shutdown(); // Construct a new socket implementation. BOOST_ASIO_DECL void construct(base_implementation_type& impl); @@ -93,6 +94,10 @@ public: BOOST_ASIO_DECL boost::system::error_code close( base_implementation_type& impl, boost::system::error_code& ec); + // Release ownership of the socket. + BOOST_ASIO_DECL socket_type release( + base_implementation_type& impl, boost::system::error_code& ec); + // Get the native socket representation. native_handle_type native_handle(base_implementation_type& impl) { @@ -163,14 +168,71 @@ public: return ec; } - // 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) + // Wait for the socket to become ready to read, ready to write, or to have + // pending error conditions. + boost::system::error_code wait(base_implementation_type& impl, + socket_base::wait_type w, boost::system::error_code& ec) { - socket_ops::shutdown(impl.socket_, what, ec); + switch (w) + { + case socket_base::wait_read: + socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); + break; + case socket_base::wait_write: + socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); + break; + case socket_base::wait_error: + socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); + break; + default: + ec = boost::asio::error::invalid_argument; + break; + } + return ec; } + // Asynchronously wait for the socket to become ready to read, ready to + // write, or to have pending error conditions. + template <typename Handler> + void async_wait(base_implementation_type& impl, + socket_base::wait_type w, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_wait_op<Handler> op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_wait")); + + int op_type; + switch (w) + { + case socket_base::wait_read: + op_type = reactor::read_op; + break; + case socket_base::wait_write: + op_type = reactor::write_op; + break; + case socket_base::wait_error: + op_type = reactor::except_op; + break; + default: + p.p->ec_ = boost::asio::error::invalid_argument; + reactor_.post_immediate_completion(p.p, is_continuation); + p.v = p.p = 0; + return; + } + + start_op(impl, op_type, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + // Send the given data to the peer. template <typename ConstBufferSequence> size_t send(base_implementation_type& impl, @@ -189,7 +251,7 @@ public: socket_base::message_flags, 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; } @@ -207,11 +269,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_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 }; - p.p = new (p.v) op(impl.socket_, buffers, flags, handler); + op::ptr::allocate(handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_send")); start_op(impl, reactor::write_op, p.p, is_continuation, true, ((impl.state_ & socket_ops::stream_oriented) @@ -231,12 +293,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_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(handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send(null_buffers)")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_send(null_buffers)")); start_op(impl, reactor::write_op, p.p, is_continuation, false, false); p.v = p.p = 0; @@ -260,7 +321,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); return 0; } @@ -278,11 +339,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_socket_recv_op<MutableBufferSequence, 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_, impl.state_, buffers, flags, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_receive")); start_op(impl, (flags & socket_base::message_out_of_band) @@ -306,12 +367,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_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(handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive(null_buffers)")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_receive(null_buffers)")); start_op(impl, (flags & socket_base::message_out_of_band) @@ -341,7 +401,7 @@ public: socket_base::message_flags& out_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); // Clear out_flags, since we cannot give it any other sensible value when // performing a null_buffers operation. @@ -363,12 +423,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_socket_recvmsg_op<MutableBufferSequence, 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_, buffers, in_flags, out_flags, handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_with_flags")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_receive_with_flags")); start_op(impl, (in_flags & socket_base::message_out_of_band) @@ -390,12 +449,11 @@ public: // Allocate and construct an operation to wrap the handler. typedef reactive_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(handler); - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); + BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", + &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); // Clear out_flags, since we cannot give it any other sensible value when // performing a null_buffers operation. @@ -432,6 +490,9 @@ protected: reactor_op* op, bool is_continuation, const socket_addr_type* addr, size_t addrlen); + // The io_context that owns this socket service. + io_context& io_context_; + // The selector that performs event demultiplexing for the service. reactor& reactor_; }; |