Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84349 - in trunk/boost/asio/detail: . impl
From: chris_at_[hidden]
Date: 2013-05-18 08:13:17


Author: chris_kohlhoff
Date: 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
New Revision: 84349
URL: http://svn.boost.org/trac/boost/changeset/84349

Log:
Fix implementation of asynchronous connect operation so that it can cope
with spurious readiness notifications from the reactor.

Text files modified:
   trunk/boost/asio/detail/impl/socket_ops.ipp | 13 ++++++++++++-
   trunk/boost/asio/detail/reactive_socket_connect_op.hpp | 21 ++++++++++++++-------
   trunk/boost/asio/detail/reactive_socket_service.hpp | 4 ++--
   trunk/boost/asio/detail/socket_ops.hpp | 5 +++--
   trunk/boost/asio/detail/win_iocp_socket_service.hpp | 4 ++--
   5 files changed, 33 insertions(+), 14 deletions(-)

Modified: trunk/boost/asio/detail/impl/socket_ops.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/socket_ops.ipp (original)
+++ trunk/boost/asio/detail/impl/socket_ops.ipp 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
@@ -508,8 +508,19 @@
       boost::asio::error::get_system_category());
 }
 
-bool non_blocking_connect(socket_type s, boost::system::error_code& ec)
+bool non_blocking_connect(socket_type s,
+ const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec)
 {
+ // Check if the connect operation has finished. This is required since we may
+ // get spurious readiness notifications from the reactor.
+ socket_ops::connect(s, addr, addrlen, ec);
+ if (ec == boost::asio::error::already_started)
+ {
+ // The asynchronous connect operation is still in progress.
+ return false;
+ }
+
   // Get the error code from the connect operation.
   int connect_error = 0;
   size_t connect_error_len = sizeof(connect_error);

Modified: trunk/boost/asio/detail/reactive_socket_connect_op.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_socket_connect_op.hpp (original)
+++ trunk/boost/asio/detail/reactive_socket_connect_op.hpp 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
@@ -29,12 +29,15 @@
 namespace asio {
 namespace detail {
 
+template <typename Protocol>
 class reactive_socket_connect_op_base : public reactor_op
 {
 public:
- reactive_socket_connect_op_base(socket_type socket, func_type complete_func)
+ reactive_socket_connect_op_base(socket_type socket,
+ const typename Protocol::endpoint& peer_endpoint, func_type complete_func)
     : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func),
- socket_(socket)
+ socket_(socket),
+ peer_endpoint_(peer_endpoint)
   {
   }
 
@@ -43,21 +46,25 @@
     reactive_socket_connect_op_base* o(
         static_cast<reactive_socket_connect_op_base*>(base));
 
- return socket_ops::non_blocking_connect(o->socket_, o->ec_);
+ return socket_ops::non_blocking_connect(o->socket_,
+ o->peer_endpoint_.data(), o->peer_endpoint_.size(), o->ec_);
   }
 
 private:
   socket_type socket_;
+ typename Protocol::endpoint peer_endpoint_;
 };
 
-template <typename Handler>
-class reactive_socket_connect_op : public reactive_socket_connect_op_base
+template <typename Protocol, typename Handler>
+class reactive_socket_connect_op :
+ public reactive_socket_connect_op_base<Protocol>
 {
 public:
   BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op);
 
- reactive_socket_connect_op(socket_type socket, Handler& handler)
- : reactive_socket_connect_op_base(socket,
+ reactive_socket_connect_op(socket_type socket,
+ const typename Protocol::endpoint& peer_endpoint, Handler& handler)
+ : reactive_socket_connect_op_base<Protocol>(socket, peer_endpoint,
         &reactive_socket_connect_op::do_complete),
       handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
   {

Modified: trunk/boost/asio/detail/reactive_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_socket_service.hpp (original)
+++ trunk/boost/asio/detail/reactive_socket_service.hpp 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
@@ -422,11 +422,11 @@
       boost_asio_handler_cont_helpers::is_continuation(handler);
 
     // Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_connect_op<Handler> op;
+ typedef reactive_socket_connect_op<Protocol, 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_, handler);
+ p.p = new (p.v) op(impl.socket_, peer_endpoint, handler);
 
     BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));
 

Modified: trunk/boost/asio/detail/socket_ops.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_ops.hpp (original)
+++ trunk/boost/asio/detail/socket_ops.hpp 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
@@ -106,8 +106,9 @@
 BOOST_ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr,
     std::size_t addrlen, boost::system::error_code& ec);
 
-BOOST_ASIO_DECL bool non_blocking_connect(
- socket_type s, boost::system::error_code& ec);
+BOOST_ASIO_DECL bool non_blocking_connect(socket_type s,
+ const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec);
 
 BOOST_ASIO_DECL int socketpair(int af, int type, int protocol,
     socket_type sv[2], boost::system::error_code& ec);

Modified: trunk/boost/asio/detail/win_iocp_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_socket_service.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_socket_service.hpp 2013-05-18 08:13:17 EDT (Sat, 18 May 2013)
@@ -484,11 +484,11 @@
       const endpoint_type& peer_endpoint, Handler& handler)
   {
     // Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_connect_op<Handler> op;
+ typedef reactive_socket_connect_op<Protocol, 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_, handler);
+ p.p = new (p.v) op(impl.socket_, peer_endpoint, handler);
 
     BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk