Fix implementation of asynchronous connect operation so that it can cope
with spurious readiness notifications from the reactor.
diff --git a/asio/include/asio/detail/impl/socket_ops.ipp b/asio/include/asio/detail/impl/socket_ops.ipp
index aaf93ab..51fbdde 100644
--- a/asio/include/asio/detail/impl/socket_ops.ipp
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
@@ -507,8 +507,19 @@
       asio::error::get_system_category());
 }
 
-bool non_blocking_connect(socket_type s, asio::error_code& ec)
+bool non_blocking_connect(socket_type s,
+    const socket_addr_type* addr, std::size_t addrlen,
+    asio::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 == 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);
diff --git a/asio/include/asio/detail/reactive_socket_connect_op.hpp b/asio/include/asio/detail/reactive_socket_connect_op.hpp
index 65f140a..7eeb049 100644
--- a/asio/include/asio/detail/reactive_socket_connect_op.hpp
+++ b/asio/include/asio/detail/reactive_socket_connect_op.hpp
@@ -28,12 +28,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)
   {
   }
 
@@ -42,21 +45,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:
   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_(ASIO_MOVE_CAST(Handler)(handler))
   {
diff --git a/asio/include/asio/detail/reactive_socket_service.hpp b/asio/include/asio/detail/reactive_socket_service.hpp
index c786733..4ef4b3f 100644
--- a/asio/include/asio/detail/reactive_socket_service.hpp
+++ b/asio/include/asio/detail/reactive_socket_service.hpp
@@ -421,11 +421,11 @@
       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 = { asio::detail::addressof(handler),
       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);
 
     ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));
 
diff --git a/asio/include/asio/detail/socket_ops.hpp b/asio/include/asio/detail/socket_ops.hpp
index 000a88b..67450ed 100644
--- a/asio/include/asio/detail/socket_ops.hpp
+++ b/asio/include/asio/detail/socket_ops.hpp
@@ -105,8 +105,9 @@
 ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr,
     std::size_t addrlen, asio::error_code& ec);
 
-ASIO_DECL bool non_blocking_connect(
-    socket_type s, asio::error_code& ec);
+ASIO_DECL bool non_blocking_connect(socket_type s,
+    const socket_addr_type* addr, std::size_t addrlen,
+    asio::error_code& ec);
 
 ASIO_DECL int socketpair(int af, int type, int protocol,
     socket_type sv[2], asio::error_code& ec);
diff --git a/asio/include/asio/detail/win_iocp_socket_service.hpp b/asio/include/asio/detail/win_iocp_socket_service.hpp
index 43e42d1..8247421 100644
--- a/asio/include/asio/detail/win_iocp_socket_service.hpp
+++ b/asio/include/asio/detail/win_iocp_socket_service.hpp
@@ -483,11 +483,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 = { asio::detail::addressof(handler),
       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);
 
     ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));