Remove swap() functions to prevent imposing dynamic memory allocations on

socket implementation.
This commit is contained in:
chris_kohlhoff 2006-01-16 06:36:56 +00:00
parent 961395f60c
commit a18bdd4790
8 changed files with 260 additions and 215 deletions

View File

@ -18,7 +18,6 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <algorithm>
#include <cstddef>
#include <boost/config.hpp>
#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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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>())),
: service_(io_service.get_service(service_factory<Service>())),
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Handler>
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 <typename Socket_Option>
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 <typename Socket_Option, typename Error_Handler>
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 <typename Socket_Option>
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 <typename Socket_Option, typename Error_Handler>
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 <typename IO_Control_Command>
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 <typename IO_Control_Command, typename Error_Handler>
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 <typename Error_Handler>
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 <typename Const_Buffers>
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 <typename Mutable_Buffers>
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<Service>& 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 <typename Service>
inline void swap(basic_datagram_socket<Service>& a,
basic_datagram_socket<Service>& b)
{
a.swap(b);
}
} // namespace asio
#include "asio/detail/pop_options.hpp"

View File

@ -17,10 +17,6 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <algorithm>
#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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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>())),
: service_(io_service.get_service(service_factory<Service>())),
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Option>
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 <typename Option, typename Error_Handler>
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 <typename Option>
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 <typename Option, typename Error_Handler>
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 <typename Error_Handler>
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 <typename Handler>
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<Service>& 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 <typename Service>
inline void swap(basic_socket_acceptor<Service>& a,
basic_socket_acceptor<Service>& b)
{
a.swap(b);
}
} // namespace asio
#include "asio/detail/pop_options.hpp"

View File

@ -18,7 +18,6 @@
#include "asio/detail/push_options.hpp"
#include "asio/detail/push_options.hpp"
#include <algorithm>
#include <cstddef>
#include <boost/config.hpp>
#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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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<Service>())),
impl_(service_->null())
: service_(io_service.get_service(service_factory<Service>())),
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>())),
: service_(io_service.get_service(service_factory<Service>())),
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Error_Handler>
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 <typename Handler>
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 <typename Socket_Option>
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 <typename Socket_Option, typename Error_Handler>
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 <typename Socket_Option>
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 <typename Socket_Option, typename Error_Handler>
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 <typename IO_Control_Command>
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 <typename IO_Control_Command, typename Error_Handler>
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 <typename Error_Handler>
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 <typename Const_Buffers>
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 <typename Mutable_Buffers>
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 <typename Const_Buffers>
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 <typename Const_Buffers, typename Handler>
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 <typename Mutable_Buffers>
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 <typename Mutable_Buffers, typename Handler>
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 <typename Mutable_Buffers>
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 <typename Mutable_Buffers, typename Error_Handler>
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<Service>& 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 <typename Service>
inline void swap(basic_stream_socket<Service>& a,
basic_stream_socket<Service>& b)
{
a.swap(b);
}
} // namespace asio
#include "asio/detail/pop_options.hpp"

View File

@ -101,9 +101,10 @@ public:
}
/// Assign a new datagram socket implementation.
void assign(impl_type& impl, impl_type new_impl)
template <typename Error_Handler>
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.

View File

@ -157,11 +157,15 @@ public:
}
// Assign a new socket implementation.
void assign(impl_type& impl, impl_type new_impl)
template <typename Error_Handler>
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;
}

View File

@ -182,7 +182,8 @@ public:
}
// Assign a new socket implementation.
void assign(impl_type& impl, impl_type new_impl)
template <typename Error_Handler>
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 <typename Socket, typename Handler>
@ -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();
}

View File

@ -97,9 +97,10 @@ public:
}
/// Assign a new datagram socket implementation.
void assign(impl_type& impl, impl_type new_impl)
template <typename Error_Handler>
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.

View File

@ -101,9 +101,10 @@ public:
}
/// Assign a new stream socket implementation.
void assign(impl_type& impl, impl_type new_impl)
template <typename Error_Handler>
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.