From a18bdd4790fa0868d38832b9d11cf192a3445d81 Mon Sep 17 00:00:00 2001 From: chris_kohlhoff Date: Mon, 16 Jan 2006 06:36:56 +0000 Subject: [PATCH] Remove swap() functions to prevent imposing dynamic memory allocations on socket implementation. --- asio/include/asio/basic_datagram_socket.hpp | 148 +++++++++-------- asio/include/asio/basic_socket_acceptor.hpp | 125 +++++++------- asio/include/asio/basic_stream_socket.hpp | 154 ++++++++++-------- asio/include/asio/datagram_socket_service.hpp | 5 +- .../asio/detail/reactive_socket_service.hpp | 18 +- .../asio/detail/win_iocp_socket_service.hpp | 15 +- asio/include/asio/socket_acceptor_service.hpp | 5 +- asio/include/asio/stream_socket_service.hpp | 5 +- 8 files changed, 260 insertions(+), 215 deletions(-) diff --git a/asio/include/asio/basic_datagram_socket.hpp b/asio/include/asio/basic_datagram_socket.hpp index 0df6ab5b..43bca373 100644 --- a/asio/include/asio/basic_datagram_socket.hpp +++ b/asio/include/asio/basic_datagram_socket.hpp @@ -18,7 +18,6 @@ #include "asio/detail/push_options.hpp" #include "asio/detail/push_options.hpp" -#include #include #include #include "asio/detail/pop_options.hpp" @@ -82,8 +81,8 @@ public: * socket. */ explicit basic_datagram_socket(io_service_type& io_service) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { } @@ -101,10 +100,10 @@ public: */ basic_datagram_socket(io_service_type& io_service, const protocol_type& protocol) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Construct a basic_datagram_socket, opening it and binding it to the given @@ -125,12 +124,12 @@ public: */ basic_datagram_socket(io_service_type& io_service, const endpoint_type& endpoint) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, endpoint.protocol(), throw_error()); + service_.open(impl_, endpoint.protocol(), throw_error()); close_on_block_exit auto_close(service_, impl_); - service_->bind(impl_, endpoint, throw_error()); + service_.bind(impl_, endpoint, throw_error()); auto_close.cancel(); } @@ -148,16 +147,16 @@ public: * @throws asio::error Thrown on failure. */ basic_datagram_socket(io_service_type& io_service, impl_type impl) - : service_(&io_service.get_service(service_factory())), + : service_(io_service.get_service(service_factory())), impl_(impl) { - service_->assign(impl_, impl); + service_.assign(impl_, impl); } /// Destructor. ~basic_datagram_socket() { - service_->close(impl_, ignore_error()); + service_.close(impl_, ignore_error()); } /// Get the io_service associated with the object. @@ -170,7 +169,7 @@ public: */ io_service_type& io_service() { - return service_->io_service(); + return service_.io_service(); } /// Open the socket using the specified protocol. @@ -190,7 +189,7 @@ public: */ void open(const protocol_type& protocol = protocol_type()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Open the socket using the specified protocol. @@ -221,7 +220,39 @@ public: template void open(const protocol_type& protocol, Error_Handler error_handler) { - service_->open(impl_, protocol, error_handler); + service_.open(impl_, protocol, error_handler); + } + + /// Open a socket on an existing implementation. + /* + * This function opens the datagram socket on an existing implementation. + * + * @param impl The new underlying socket implementation. + * + * @throws asio::error Thrown on failure. + */ + void open(impl_type impl) + { + service_.open(impl_, impl, throw_error()); + } + + /// Open a socket on an existing implementation. + /* + * This function opens the datagram socket on an existing implementation. + * + * @param impl The new underlying socket implementation. + * + * @param error_handler The handler to be called when an error occurs. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void error_handler( + * const asio::error& error // Result of operation + * ); @endcode + */ + template + void open(impl_type impl, Error_Handler error_handler) + { + service_.open(impl_, impl, error_handler); } /// Close the socket. @@ -236,7 +267,7 @@ public: */ void close() { - service_->close(impl_, throw_error()); + service_.close(impl_, throw_error()); } /// Close the socket. @@ -269,7 +300,7 @@ public: template void close(Error_Handler error_handler) { - service_->close(impl_, error_handler); + service_.close(impl_, error_handler); } /// Get a reference to the lowest layer. @@ -306,7 +337,7 @@ public: */ void set_impl(impl_type new_impl) { - service_->assign(impl_, new_impl); + service_.assign(impl_, new_impl); } /// Bind the socket to the given local endpoint. @@ -328,7 +359,7 @@ public: */ void bind(const endpoint_type& endpoint) { - service_->bind(impl_, endpoint, throw_error()); + service_.bind(impl_, endpoint, throw_error()); } /// Bind the socket to the given local endpoint. @@ -362,7 +393,7 @@ public: template void bind(const endpoint_type& endpoint, Error_Handler error_handler) { - service_->bind(impl_, endpoint, error_handler); + service_.bind(impl_, endpoint, error_handler); } /// Connect a datagram socket to the specified endpoint. @@ -390,7 +421,7 @@ public: */ void connect(const endpoint_type& peer_endpoint) { - service_->connect(impl_, peer_endpoint, throw_error()); + service_.connect(impl_, peer_endpoint, throw_error()); } /// Connect a datagram socket to the specified endpoint. @@ -429,7 +460,7 @@ public: template void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler) { - service_->connect(impl_, peer_endpoint, error_handler); + service_.connect(impl_, peer_endpoint, error_handler); } /// Start an asynchronous connect. @@ -476,7 +507,7 @@ public: template void async_connect(const endpoint_type& peer_endpoint, Handler handler) { - service_->async_connect(impl_, peer_endpoint, handler); + service_.async_connect(impl_, peer_endpoint, handler); } /// Set an option on the socket. @@ -509,7 +540,7 @@ public: template void set_option(const Socket_Option& option) { - service_->set_option(impl_, option, throw_error()); + service_.set_option(impl_, option, throw_error()); } /// Set an option on the socket. @@ -552,7 +583,7 @@ public: template void set_option(const Socket_Option& option, Error_Handler error_handler) { - service_->set_option(impl_, option, error_handler); + service_.set_option(impl_, option, error_handler); } /// Get an option from the socket. @@ -586,7 +617,7 @@ public: template void get_option(Socket_Option& option) const { - service_->get_option(impl_, option, throw_error()); + service_.get_option(impl_, option, throw_error()); } /// Get an option from the socket. @@ -630,7 +661,7 @@ public: template void get_option(Socket_Option& option, Error_Handler error_handler) const { - service_->get_option(impl_, option, error_handler); + service_.get_option(impl_, option, error_handler); } /// Perform an IO control command on the socket. @@ -658,7 +689,7 @@ public: template void io_control(IO_Control_Command& command) { - service_->io_control(impl_, command, throw_error()); + service_.io_control(impl_, command, throw_error()); } /// Perform an IO control command on the socket. @@ -696,7 +727,7 @@ public: template void io_control(IO_Control_Command& command, Error_Handler error_handler) { - service_->io_control(impl_, command, error_handler); + service_.io_control(impl_, command, error_handler); } /// Get the local endpoint of the socket. @@ -718,7 +749,7 @@ public: */ void get_local_endpoint(endpoint_type& endpoint) const { - service_->get_local_endpoint(impl_, endpoint, throw_error()); + service_.get_local_endpoint(impl_, endpoint, throw_error()); } /// Get the local endpoint of the socket. @@ -752,7 +783,7 @@ public: void get_local_endpoint(endpoint_type& endpoint, Error_Handler error_handler) const { - service_->get_local_endpoint(impl_, endpoint, error_handler); + service_.get_local_endpoint(impl_, endpoint, error_handler); } /// Get the remote endpoint of the socket. @@ -774,7 +805,7 @@ public: */ void get_remote_endpoint(endpoint_type& endpoint) const { - service_->get_remote_endpoint(impl_, endpoint, throw_error()); + service_.get_remote_endpoint(impl_, endpoint, throw_error()); } /// Get the remote endpoint of the socket. @@ -808,7 +839,7 @@ public: void get_remote_endpoint(endpoint_type& endpoint, Error_Handler error_handler) const { - service_->get_remote_endpoint(impl_, endpoint, error_handler); + service_.get_remote_endpoint(impl_, endpoint, error_handler); } /// Disable sends or receives on the socket. @@ -830,7 +861,7 @@ public: */ void shutdown(shutdown_type what) { - service_->shutdown(impl_, what, throw_error()); + service_.shutdown(impl_, what, throw_error()); } /// Disable sends or receives on the socket. @@ -864,7 +895,7 @@ public: template void shutdown(shutdown_type what, Error_Handler error_handler) { - service_->shutdown(impl_, what, error_handler); + service_.shutdown(impl_, what, error_handler); } /// Send some data on a connected socket. @@ -894,7 +925,7 @@ public: template std::size_t send(const Const_Buffers& buffers, message_flags flags) { - return service_->send(impl_, buffers, flags, throw_error()); + return service_.send(impl_, buffers, flags, throw_error()); } /// Send some data on a connected socket. @@ -923,7 +954,7 @@ public: std::size_t send(const Const_Buffers& buffers, message_flags flags, Error_Handler error_handler) { - return service_->send(impl_, buffers, flags, error_handler); + return service_.send(impl_, buffers, flags, error_handler); } /// Start an asynchronous send on a connected socket. @@ -968,7 +999,7 @@ public: void async_send(const Const_Buffers& buffers, message_flags flags, Handler handler) { - service_->async_send(impl_, buffers, flags, handler); + service_.async_send(impl_, buffers, flags, handler); } /// Send a datagram to the specified endpoint. @@ -1001,7 +1032,7 @@ public: std::size_t send_to(const Const_Buffers& buffers, message_flags flags, const endpoint_type& destination) { - return service_->send_to(impl_, buffers, flags, destination, throw_error()); + return service_.send_to(impl_, buffers, flags, destination, throw_error()); } /// Send a datagram to the specified endpoint. @@ -1029,7 +1060,7 @@ public: std::size_t send_to(const Const_Buffers& buffers, message_flags flags, const endpoint_type& destination, Error_Handler error_handler) { - return service_->send_to(impl_, buffers, flags, destination, error_handler); + return service_.send_to(impl_, buffers, flags, destination, error_handler); } /// Start an asynchronous send. @@ -1074,7 +1105,7 @@ public: void async_send_to(const Const_Buffers& buffers, message_flags flags, const endpoint_type& destination, Handler handler) { - service_->async_send_to(impl_, buffers, flags, destination, handler); + service_.async_send_to(impl_, buffers, flags, destination, handler); } /// Receive some data on a connected socket. @@ -1106,7 +1137,7 @@ public: template std::size_t receive(const Mutable_Buffers& buffers, message_flags flags) { - return service_->receive(impl_, buffers, flags, throw_error()); + return service_.receive(impl_, buffers, flags, throw_error()); } /// Receive some data on a connected socket. @@ -1136,7 +1167,7 @@ public: std::size_t receive(const Mutable_Buffers& buffers, message_flags flags, Error_Handler error_handler) { - return service_->receive(impl_, buffers, flags, error_handler); + return service_.receive(impl_, buffers, flags, error_handler); } /// Start an asynchronous receive on a connected socket. @@ -1181,7 +1212,7 @@ public: void async_receive(const Mutable_Buffers& buffers, message_flags flags, Handler handler) { - service_->async_receive(impl_, buffers, flags, handler); + service_.async_receive(impl_, buffers, flags, handler); } /// Receive a datagram with the endpoint of the sender. @@ -1216,7 +1247,7 @@ public: std::size_t receive_from(const Mutable_Buffers& buffers, message_flags flags, endpoint_type& sender_endpoint) { - return service_->receive_from(impl_, buffers, flags, sender_endpoint, + return service_.receive_from(impl_, buffers, flags, sender_endpoint, throw_error()); } @@ -1245,7 +1276,7 @@ public: std::size_t receive_from(const Mutable_Buffers& buffers, message_flags flags, endpoint_type& sender_endpoint, Error_Handler error_handler) { - return service_->receive_from(impl_, buffers, flags, sender_endpoint, + return service_.receive_from(impl_, buffers, flags, sender_endpoint, error_handler); } @@ -1291,20 +1322,13 @@ public: void async_receive_from(const Mutable_Buffers& buffers, message_flags flags, endpoint_type& sender_endpoint, Handler handler) { - service_->async_receive_from(impl_, buffers, flags, sender_endpoint, + service_.async_receive_from(impl_, buffers, flags, sender_endpoint, handler); } - /// Swap implementation of socket with another. - void swap(basic_datagram_socket& other) - { - std::swap(service_, other.service_); - std::swap(impl_, other.impl_); - } - private: /// The backend service implementation. - service_type* service_; + service_type& service_; /// The underlying native implementation. impl_type impl_; @@ -1313,8 +1337,8 @@ private: class close_on_block_exit { public: - close_on_block_exit(service_type* service, impl_type& impl) - : service_(service), impl_(impl) + close_on_block_exit(service_type& service, impl_type& impl) + : service_(&service), impl_(impl) { } @@ -1337,14 +1361,6 @@ private: }; }; -/// Swap implementation of socket with another. -template -inline void swap(basic_datagram_socket& a, - basic_datagram_socket& b) -{ - a.swap(b); -} - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/asio/include/asio/basic_socket_acceptor.hpp b/asio/include/asio/basic_socket_acceptor.hpp index b84b6f50..68d0d0a6 100644 --- a/asio/include/asio/basic_socket_acceptor.hpp +++ b/asio/include/asio/basic_socket_acceptor.hpp @@ -17,10 +17,6 @@ #include "asio/detail/push_options.hpp" -#include "asio/detail/push_options.hpp" -#include -#include "asio/detail/pop_options.hpp" - #include "asio/error.hpp" #include "asio/error_handler.hpp" #include "asio/service_factory.hpp" @@ -92,8 +88,8 @@ public: * acceptor. */ explicit basic_socket_acceptor(io_service_type& io_service) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { } @@ -111,10 +107,10 @@ public: */ basic_socket_acceptor(io_service_type& io_service, const protocol_type& protocol) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Construct an acceptor opened on the given endpoint. @@ -144,13 +140,13 @@ public: */ basic_socket_acceptor(io_service_type& io_service, const endpoint_type& endpoint, int listen_backlog = 0) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, endpoint.protocol(), throw_error()); + service_.open(impl_, endpoint.protocol(), throw_error()); close_on_block_exit auto_close(service_, impl_); - service_->bind(impl_, endpoint, throw_error()); - service_->listen(impl_, listen_backlog, throw_error()); + service_.bind(impl_, endpoint, throw_error()); + service_.listen(impl_, listen_backlog, throw_error()); auto_close.cancel(); } @@ -166,16 +162,16 @@ public: * @throws asio::error Thrown on failure. */ basic_socket_acceptor(io_service_type& io_service, impl_type impl) - : service_(&io_service.get_service(service_factory())), + : service_(io_service.get_service(service_factory())), impl_(impl) { - service_->assign(impl_, impl); + service_.assign(impl_, impl); } /// Destructor. ~basic_socket_acceptor() { - service_->close(impl_, ignore_error()); + service_.close(impl_, ignore_error()); } /// Get the io_service associated with the object. @@ -188,7 +184,7 @@ public: */ io_service_type& io_service() { - return service_->io_service(); + return service_.io_service(); } /// Open the acceptor using the specified protocol. @@ -206,7 +202,7 @@ public: */ void open(const protocol_type& protocol = protocol_type()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Open the acceptor using the specified protocol. @@ -237,7 +233,39 @@ public: template void open(const protocol_type& protocol, Error_Handler error_handler) { - service_->open(impl_, protocol, error_handler); + service_.open(impl_, protocol, error_handler); + } + + /// Open an acceptor on an existing implementation. + /* + * This function opens the acceptor on an existing implementation. + * + * @param impl The new underlying acceptor implementation. + * + * @throws asio::error Thrown on failure. + */ + void open(impl_type impl) + { + service_.open(impl_, impl, throw_error()); + } + + /// Open an acceptor on an existing implementation. + /* + * This function opens the acceptor on an existing implementation. + * + * @param impl The new underlying acceptor implementation. + * + * @param error_handler The handler to be called when an error occurs. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void error_handler( + * const asio::error& error // Result of operation + * ); @endcode + */ + template + void open(impl_type impl, Error_Handler error_handler) + { + service_.open(impl_, impl, error_handler); } /// Bind the acceptor to the given local endpoint. @@ -259,7 +287,7 @@ public: */ void bind(const endpoint_type& endpoint) { - service_->bind(impl_, endpoint, throw_error()); + service_.bind(impl_, endpoint, throw_error()); } /// Bind the acceptor to the given local endpoint. @@ -293,7 +321,7 @@ public: template void bind(const endpoint_type& endpoint, Error_Handler error_handler) { - service_->bind(impl_, endpoint, error_handler); + service_.bind(impl_, endpoint, error_handler); } /// Place the acceptor into the state where it will listen for new @@ -307,7 +335,7 @@ public: */ void listen(int backlog = 0) { - service_->listen(impl_, backlog, throw_error()); + service_.listen(impl_, backlog, throw_error()); } /// Place the acceptor into the state where it will listen for new @@ -341,7 +369,7 @@ public: template void listen(int backlog, Error_Handler error_handler) { - service_->listen(impl_, backlog, error_handler); + service_.listen(impl_, backlog, error_handler); } /// Close the acceptor. @@ -356,7 +384,7 @@ public: */ void close() { - service_->close(impl_, throw_error()); + service_.close(impl_, throw_error()); } /// Close the acceptor. @@ -389,7 +417,7 @@ public: template void close(Error_Handler error_handler) { - service_->close(impl_, error_handler); + service_.close(impl_, error_handler); } /// Get the underlying implementation in the native type. @@ -426,7 +454,7 @@ public: template void set_option(const Option& option) { - service_->set_option(impl_, option, throw_error()); + service_.set_option(impl_, option, throw_error()); } /// Set an option on the acceptor. @@ -462,7 +490,7 @@ public: template void set_option(const Option& option, Error_Handler error_handler) { - service_->set_option(impl_, option, error_handler); + service_.set_option(impl_, option, error_handler); } /// Get an option from the acceptor. @@ -490,7 +518,7 @@ public: template void get_option(Option& option) { - service_->get_option(impl_, option, throw_error()); + service_.get_option(impl_, option, throw_error()); } /// Get an option from the acceptor. @@ -528,7 +556,7 @@ public: template void get_option(Option& option, Error_Handler error_handler) { - service_->get_option(impl_, option, error_handler); + service_.get_option(impl_, option, error_handler); } /// Get the local endpoint of the acceptor. @@ -551,7 +579,7 @@ public: */ void get_local_endpoint(endpoint_type& endpoint) const { - service_->get_local_endpoint(impl_, endpoint, throw_error()); + service_.get_local_endpoint(impl_, endpoint, throw_error()); } /// Get the local endpoint of the acceptor. @@ -586,7 +614,7 @@ public: void get_local_endpoint(endpoint_type& endpoint, Error_Handler error_handler) const { - service_->get_local_endpoint(impl_, endpoint, error_handler); + service_.get_local_endpoint(impl_, endpoint, error_handler); } /// Accept a new connection. @@ -609,7 +637,7 @@ public: */ void accept(socket_type& peer) { - service_->accept(impl_, peer, throw_error()); + service_.accept(impl_, peer, throw_error()); } /// Accept a new connection. @@ -643,7 +671,7 @@ public: template void accept(socket_type& peer, Error_Handler error_handler) { - service_->accept(impl_, peer, error_handler); + service_.accept(impl_, peer, error_handler); } /// Start an asynchronous accept. @@ -687,7 +715,7 @@ public: template void async_accept(socket_type& peer, Handler handler) { - service_->async_accept(impl_, peer, handler); + service_.async_accept(impl_, peer, handler); } /// Accept a new connection and obtain the endpoint of the peer @@ -715,7 +743,7 @@ public: */ void accept_endpoint(socket_type& peer, endpoint_type& peer_endpoint) { - service_->accept_endpoint(impl_, peer, peer_endpoint, throw_error()); + service_.accept_endpoint(impl_, peer, peer_endpoint, throw_error()); } /// Accept a new connection and obtain the endpoint of the peer @@ -756,7 +784,7 @@ public: void accept_endpoint(socket_type& peer, endpoint_type& peer_endpoint, Error_Handler error_handler) { - service_->accept_endpoint(impl_, peer, peer_endpoint, error_handler); + service_.accept_endpoint(impl_, peer, peer_endpoint, error_handler); } /// Start an asynchronous accept. @@ -789,19 +817,12 @@ public: void async_accept_endpoint(socket_type& peer, endpoint_type& peer_endpoint, Handler handler) { - service_->async_accept_endpoint(impl_, peer, peer_endpoint, handler); - } - - /// Swap implementation of socket with another. - void swap(basic_socket_acceptor& other) - { - std::swap(service_, other.service_); - std::swap(impl_, other.impl_); + service_.async_accept_endpoint(impl_, peer, peer_endpoint, handler); } private: /// The backend service implementation. - service_type* service_; + service_type& service_; /// The underlying native implementation. impl_type impl_; @@ -810,8 +831,8 @@ private: class close_on_block_exit { public: - close_on_block_exit(service_type* service, impl_type& impl) - : service_(service), impl_(impl) + close_on_block_exit(service_type& service, impl_type& impl) + : service_(&service), impl_(impl) { } @@ -834,14 +855,6 @@ private: }; }; -/// Swap implementation of socket with another. -template -inline void swap(basic_socket_acceptor& a, - basic_socket_acceptor& b) -{ - a.swap(b); -} - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/asio/include/asio/basic_stream_socket.hpp b/asio/include/asio/basic_stream_socket.hpp index acf499a9..c814cdc2 100644 --- a/asio/include/asio/basic_stream_socket.hpp +++ b/asio/include/asio/basic_stream_socket.hpp @@ -18,7 +18,6 @@ #include "asio/detail/push_options.hpp" #include "asio/detail/push_options.hpp" -#include #include #include #include "asio/detail/pop_options.hpp" @@ -81,8 +80,8 @@ public: * dispatch handlers for any asynchronous operations performed on the socket. */ explicit basic_stream_socket(io_service_type& io_service) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { } @@ -100,10 +99,10 @@ public: */ basic_stream_socket(io_service_type& io_service, const protocol_type& protocol) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Construct a basic_stream_socket, opening it and binding it to the given @@ -123,12 +122,12 @@ public: */ basic_stream_socket(io_service_type& io_service, const endpoint_type& endpoint) - : service_(&io_service.get_service(service_factory())), - impl_(service_->null()) + : service_(io_service.get_service(service_factory())), + impl_(service_.null()) { - service_->open(impl_, endpoint.protocol(), throw_error()); + service_.open(impl_, endpoint.protocol(), throw_error()); close_on_block_exit auto_close(service_, impl_); - service_->bind(impl_, endpoint, throw_error()); + service_.bind(impl_, endpoint, throw_error()); auto_close.cancel(); } @@ -145,16 +144,16 @@ public: * @throws asio::error Thrown on failure. */ basic_stream_socket(io_service_type& io_service, impl_type impl) - : service_(&io_service.get_service(service_factory())), + : service_(io_service.get_service(service_factory())), impl_(impl) { - service_->assign(impl_, impl); + service_.open(impl_, impl, throw_error()); } /// Destructor. ~basic_stream_socket() { - service_->close(impl_, ignore_error()); + service_.close(impl_, ignore_error()); } /// Get the io_service associated with the object. @@ -167,7 +166,7 @@ public: */ io_service_type& io_service() { - return service_->io_service(); + return service_.io_service(); } /// Open the socket using the specified protocol. @@ -187,7 +186,7 @@ public: */ void open(const protocol_type& protocol = protocol_type()) { - service_->open(impl_, protocol, throw_error()); + service_.open(impl_, protocol, throw_error()); } /// Open the socket using the specified protocol. @@ -218,7 +217,39 @@ public: template void open(const protocol_type& protocol, Error_Handler error_handler) { - service_->open(impl_, protocol, error_handler); + service_.open(impl_, protocol, error_handler); + } + + /// Open a socket on an existing implementation. + /* + * This function opens the stream socket on an existing implementation. + * + * @param impl The new underlying socket implementation. + * + * @throws asio::error Thrown on failure. + */ + void open(impl_type impl) + { + service_.open(impl_, impl, throw_error()); + } + + /// Open a socket on an existing implementation. + /* + * This function opens the stream socket on an existing implementation. + * + * @param impl The new underlying socket implementation. + * + * @param error_handler The handler to be called when an error occurs. Copies + * will be made of the handler as required. The function signature of the + * handler must be: + * @code void error_handler( + * const asio::error& error // Result of operation + * ); @endcode + */ + template + void open(impl_type impl, Error_Handler error_handler) + { + service_.open(impl_, impl, error_handler); } /// Close the socket. @@ -230,7 +261,7 @@ public: */ void close() { - service_->close(impl_, throw_error()); + service_.close(impl_, throw_error()); } /// Close the socket. @@ -260,7 +291,7 @@ public: template void close(Error_Handler error_handler) { - service_->close(impl_, error_handler); + service_.close(impl_, error_handler); } /// Get a reference to the lowest layer. @@ -307,7 +338,7 @@ public: */ void bind(const endpoint_type& endpoint) { - service_->bind(impl_, endpoint, throw_error()); + service_.bind(impl_, endpoint, throw_error()); } /// Bind the socket to the given local endpoint. @@ -341,7 +372,7 @@ public: template void bind(const endpoint_type& endpoint, Error_Handler error_handler) { - service_->bind(impl_, endpoint, error_handler); + service_.bind(impl_, endpoint, error_handler); } /// Connect a stream socket to the specified endpoint. @@ -368,7 +399,7 @@ public: */ void connect(const endpoint_type& peer_endpoint) { - service_->connect(impl_, peer_endpoint, throw_error()); + service_.connect(impl_, peer_endpoint, throw_error()); } /// Connect a stream socket to the specified endpoint. @@ -406,7 +437,7 @@ public: template void connect(const endpoint_type& peer_endpoint, Error_Handler error_handler) { - service_->connect(impl_, peer_endpoint, error_handler); + service_.connect(impl_, peer_endpoint, error_handler); } /// Start an asynchronous connect. @@ -452,7 +483,7 @@ public: template void async_connect(const endpoint_type& peer_endpoint, Handler handler) { - service_->async_connect(impl_, peer_endpoint, handler); + service_.async_connect(impl_, peer_endpoint, handler); } /// Set an option on the socket. @@ -484,7 +515,7 @@ public: template void set_option(const Socket_Option& option) { - service_->set_option(impl_, option, throw_error()); + service_.set_option(impl_, option, throw_error()); } /// Set an option on the socket. @@ -526,7 +557,7 @@ public: template void set_option(const Socket_Option& option, Error_Handler error_handler) { - service_->set_option(impl_, option, error_handler); + service_.set_option(impl_, option, error_handler); } /// Get an option from the socket. @@ -559,7 +590,7 @@ public: template void get_option(Socket_Option& option) const { - service_->get_option(impl_, option, throw_error()); + service_.get_option(impl_, option, throw_error()); } /// Get an option from the socket. @@ -602,7 +633,7 @@ public: template void get_option(Socket_Option& option, Error_Handler error_handler) const { - service_->get_option(impl_, option, error_handler); + service_.get_option(impl_, option, error_handler); } /// Perform an IO control command on the socket. @@ -630,7 +661,7 @@ public: template void io_control(IO_Control_Command& command) { - service_->io_control(impl_, command, throw_error()); + service_.io_control(impl_, command, throw_error()); } /// Perform an IO control command on the socket. @@ -668,7 +699,7 @@ public: template void io_control(IO_Control_Command& command, Error_Handler error_handler) { - service_->io_control(impl_, command, error_handler); + service_.io_control(impl_, command, error_handler); } /// Get the local endpoint of the socket. @@ -690,7 +721,7 @@ public: */ void get_local_endpoint(endpoint_type& endpoint) const { - service_->get_local_endpoint(impl_, endpoint, throw_error()); + service_.get_local_endpoint(impl_, endpoint, throw_error()); } /// Get the local endpoint of the socket. @@ -724,7 +755,7 @@ public: void get_local_endpoint(endpoint_type& endpoint, Error_Handler error_handler) const { - service_->get_local_endpoint(impl_, endpoint, error_handler); + service_.get_local_endpoint(impl_, endpoint, error_handler); } /// Get the remote endpoint of the socket. @@ -746,7 +777,7 @@ public: */ void get_remote_endpoint(endpoint_type& endpoint) const { - service_->get_remote_endpoint(impl_, endpoint, throw_error()); + service_.get_remote_endpoint(impl_, endpoint, throw_error()); } /// Get the remote endpoint of the socket. @@ -780,7 +811,7 @@ public: void get_remote_endpoint(endpoint_type& endpoint, Error_Handler error_handler) const { - service_->get_remote_endpoint(impl_, endpoint, error_handler); + service_.get_remote_endpoint(impl_, endpoint, error_handler); } /// Disable sends or receives on the socket. @@ -802,7 +833,7 @@ public: */ void shutdown(shutdown_type what) { - service_->shutdown(impl_, what, throw_error()); + service_.shutdown(impl_, what, throw_error()); } /// Disable sends or receives on the socket. @@ -836,7 +867,7 @@ public: template void shutdown(shutdown_type what, Error_Handler error_handler) { - service_->shutdown(impl_, what, error_handler); + service_.shutdown(impl_, what, error_handler); } /// Send some data on the socket. @@ -869,7 +900,7 @@ public: template std::size_t send(const Const_Buffers& buffers, message_flags flags) { - return service_->send(impl_, buffers, flags, throw_error()); + return service_.send(impl_, buffers, flags, throw_error()); } /// Send some data on the socket. @@ -900,7 +931,7 @@ public: std::size_t send(const Const_Buffers& buffers, message_flags flags, Error_Handler error_handler) { - return service_->send(impl_, buffers, flags, error_handler); + return service_.send(impl_, buffers, flags, error_handler); } /// Start an asynchronous send. @@ -944,7 +975,7 @@ public: void async_send(const Const_Buffers& buffers, message_flags flags, Handler handler) { - service_->async_send(impl_, buffers, flags, handler); + service_.async_send(impl_, buffers, flags, handler); } /// Receive some data on the socket. @@ -980,7 +1011,7 @@ public: template std::size_t receive(const Mutable_Buffers& buffers, message_flags flags) { - return service_->receive(impl_, buffers, flags, throw_error()); + return service_.receive(impl_, buffers, flags, throw_error()); } /// Receive some data on a connected socket. @@ -1011,7 +1042,7 @@ public: std::size_t receive(const Mutable_Buffers& buffers, message_flags flags, Error_Handler error_handler) { - return service_->receive(impl_, buffers, flags, error_handler); + return service_.receive(impl_, buffers, flags, error_handler); } /// Start an asynchronous receive. @@ -1057,7 +1088,7 @@ public: void async_receive(const Mutable_Buffers& buffers, message_flags flags, Handler handler) { - service_->async_receive(impl_, buffers, flags, handler); + service_.async_receive(impl_, buffers, flags, handler); } /// Write some data to the socket. @@ -1090,7 +1121,7 @@ public: template std::size_t write_some(const Const_Buffers& buffers) { - return service_->send(impl_, buffers, 0, throw_error()); + return service_.send(impl_, buffers, 0, throw_error()); } /// Write some data to the socket. @@ -1119,7 +1150,7 @@ public: std::size_t write_some(const Const_Buffers& buffers, Error_Handler error_handler) { - return service_->send(impl_, buffers, 0, error_handler); + return service_.send(impl_, buffers, 0, error_handler); } /// Start an asynchronous write. @@ -1160,7 +1191,7 @@ public: template void async_write_some(const Const_Buffers& buffers, Handler handler) { - service_->async_send(impl_, buffers, 0, handler); + service_.async_send(impl_, buffers, 0, handler); } /// Read some data from the socket. @@ -1194,7 +1225,7 @@ public: template std::size_t read_some(const Mutable_Buffers& buffers) { - return service_->receive(impl_, buffers, 0, throw_error()); + return service_.receive(impl_, buffers, 0, throw_error()); } /// Read some data from the socket. @@ -1224,7 +1255,7 @@ public: std::size_t read_some(const Mutable_Buffers& buffers, Error_Handler error_handler) { - return service_->receive(impl_, buffers, 0, error_handler); + return service_.receive(impl_, buffers, 0, error_handler); } /// Start an asynchronous read. @@ -1266,7 +1297,7 @@ public: template void async_read_some(const Mutable_Buffers& buffers, Handler handler) { - service_->async_receive(impl_, buffers, 0, handler); + service_.async_receive(impl_, buffers, 0, handler); } /// Peek at the incoming data on the stream socket. @@ -1292,7 +1323,7 @@ public: template std::size_t peek(const Mutable_Buffers& buffers) { - return service_->receive(impl_, buffers, message_peek, throw_error()); + return service_.receive(impl_, buffers, message_peek, throw_error()); } /// Peek at the incoming data on the stream socket. @@ -1316,7 +1347,7 @@ public: template std::size_t peek(const Mutable_Buffers& buffers, Error_Handler error_handler) { - return service_->receive(impl_, buffers, message_peek, error_handler); + return service_.receive(impl_, buffers, message_peek, error_handler); } /// Determine the amount of data that may be read without blocking. @@ -1331,7 +1362,7 @@ public: std::size_t in_avail() { bytes_readable command; - service_->io_control(impl_, command, throw_error()); + service_.io_control(impl_, command, throw_error()); return command.get(); } @@ -1353,20 +1384,13 @@ public: std::size_t in_avail(Error_Handler error_handler) { bytes_readable command; - service_->io_control(impl_, command, error_handler); + service_.io_control(impl_, command, error_handler); return command.get(); } - /// Swap implementation of socket with another. - void swap(basic_stream_socket& other) - { - std::swap(service_, other.service_); - std::swap(impl_, other.impl_); - } - private: /// The backend service implementation. - service_type* service_; + service_type& service_; /// The underlying native implementation. impl_type impl_; @@ -1375,8 +1399,8 @@ private: class close_on_block_exit { public: - close_on_block_exit(service_type* service, impl_type& impl) - : service_(service), impl_(impl) + close_on_block_exit(service_type& service, impl_type& impl) + : service_(&service), impl_(impl) { } @@ -1399,14 +1423,6 @@ private: }; }; -/// Swap implementation of socket with another. -template -inline void swap(basic_stream_socket& a, - basic_stream_socket& b) -{ - a.swap(b); -} - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/asio/include/asio/datagram_socket_service.hpp b/asio/include/asio/datagram_socket_service.hpp index 650d0bfa..6f98d13c 100644 --- a/asio/include/asio/datagram_socket_service.hpp +++ b/asio/include/asio/datagram_socket_service.hpp @@ -101,9 +101,10 @@ public: } /// Assign a new datagram socket implementation. - void assign(impl_type& impl, impl_type new_impl) + template + void open(impl_type& impl, impl_type new_impl, Error_Handler error_handler) { - service_impl_.assign(impl, new_impl); + service_impl_.open(impl, new_impl, error_handler); } /// Close a stream socket implementation. diff --git a/asio/include/asio/detail/reactive_socket_service.hpp b/asio/include/asio/detail/reactive_socket_service.hpp index 997adfb5..427f7302 100644 --- a/asio/include/asio/detail/reactive_socket_service.hpp +++ b/asio/include/asio/detail/reactive_socket_service.hpp @@ -157,11 +157,15 @@ public: } // Assign a new socket implementation. - void assign(impl_type& impl, impl_type new_impl) + template + void open(impl_type& impl, impl_type new_impl, Error_Handler error_handler) { int err = reactor_.register_descriptor(new_impl); if (err) + { + error_handler(asio::error(err)); return; + } impl = new_impl; } @@ -920,8 +924,7 @@ public: if (new_socket >= 0) { impl_type new_impl(new_socket); - Socket tmp(peer.io_service(), new_impl); - tmp.swap(peer); + peer.open(new_impl); return; } @@ -976,8 +979,7 @@ public: { peer_endpoint.size(addr_len); impl_type new_impl(new_socket); - Socket tmp(peer.io_service(), new_impl); - tmp.swap(peer); + peer.open(new_impl); return; } @@ -1035,8 +1037,7 @@ public: return false; impl_type new_impl(new_socket); - Socket tmp(peer_.io_service(), new_impl); - tmp.swap(peer_); + peer_.open(new_impl); io_service_.post(bind_handler(handler_, error)); return true; } @@ -1123,8 +1124,7 @@ public: peer_endpoint_.size(addr_len); impl_type new_impl(new_socket); - Socket tmp(peer_.io_service(), new_impl); - tmp.swap(peer_); + peer_.open(new_impl); io_service_.post(bind_handler(handler_, error)); return true; } diff --git a/asio/include/asio/detail/win_iocp_socket_service.hpp b/asio/include/asio/detail/win_iocp_socket_service.hpp index e98fe2f8..f9c9e15b 100644 --- a/asio/include/asio/detail/win_iocp_socket_service.hpp +++ b/asio/include/asio/detail/win_iocp_socket_service.hpp @@ -182,7 +182,8 @@ public: } // Assign a new socket implementation. - void assign(impl_type& impl, impl_type new_impl) + template + void open(impl_type& impl, impl_type new_impl, Error_Handler error_handler) { iocp_service_.register_socket(new_impl); impl = new_impl; @@ -847,8 +848,7 @@ public: return; } - Socket tmp(peer.io_service(), new_socket); - tmp.swap(peer); + peer.open(new_socket); } // Accept a new connection. @@ -874,8 +874,7 @@ public: peer_endpoint.size(addr_len); - Socket tmp(peer.io_service(), new_socket); - tmp.swap(peer); + peer.open(new_socket); } template @@ -946,8 +945,7 @@ public: if (last_error == 0) { impl_type new_socket(handler_op->new_socket_.get()); - Socket tmp(handler_op->peer_.io_service(), new_socket); - tmp.swap(handler_op->peer_); + handler_op->peer_.open(new_socket); handler_op->new_socket_.release(); } @@ -1136,8 +1134,7 @@ public: if (last_error == 0) { impl_type new_socket(handler_op->new_socket_.get()); - Socket tmp(handler_op->peer_.io_service(), new_socket); - tmp.swap(handler_op->peer_); + handler_op->peer_.open(new_socket); handler_op->new_socket_.release(); } diff --git a/asio/include/asio/socket_acceptor_service.hpp b/asio/include/asio/socket_acceptor_service.hpp index 34f2af96..2b72fd63 100644 --- a/asio/include/asio/socket_acceptor_service.hpp +++ b/asio/include/asio/socket_acceptor_service.hpp @@ -97,9 +97,10 @@ public: } /// Assign a new datagram socket implementation. - void assign(impl_type& impl, impl_type new_impl) + template + void open(impl_type& impl, impl_type new_impl, Error_Handler error_handler) { - service_impl_.assign(impl, new_impl); + service_impl_.open(impl, new_impl, error_handler); } /// Bind the socket acceptor to the specified local endpoint. diff --git a/asio/include/asio/stream_socket_service.hpp b/asio/include/asio/stream_socket_service.hpp index fec9be0d..c85484da 100644 --- a/asio/include/asio/stream_socket_service.hpp +++ b/asio/include/asio/stream_socket_service.hpp @@ -101,9 +101,10 @@ public: } /// Assign a new stream socket implementation. - void assign(impl_type& impl, impl_type new_impl) + template + void open(impl_type& impl, impl_type new_impl, Error_Handler error_handler) { - service_impl_.assign(impl, new_impl); + service_impl_.open(impl, new_impl, error_handler); } /// Close a stream socket implementation.