$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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"));