summaryrefslogtreecommitdiffstats
path: root/net/socket/tcp_socket_win.cc
diff options
context:
space:
mode:
authorrpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-03 17:32:21 +0000
committerrpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-03 17:32:21 +0000
commit79b168fdf65878b6c7f5a1ddc952272acfbca3bb (patch)
tree3f70850f634f94ad7edd0b315a33025062930511 /net/socket/tcp_socket_win.cc
parent110da40adb80643c8f2f9331fc037c3b826e9cdb (diff)
downloadchromium_src-79b168fdf65878b6c7f5a1ddc952272acfbca3bb.zip
chromium_src-79b168fdf65878b6c7f5a1ddc952272acfbca3bb.tar.gz
chromium_src-79b168fdf65878b6c7f5a1ddc952272acfbca3bb.tar.bz2
Fix bug 170595
On Windows, TCPSocketWin can reach a state where it won't "accept" new connections on a server socket. It looks like WSAEnumSocketEvents has some undocumented behavior: the lNetworkEvents member of WSANETWORKEVENTS is zero in some cases. We found this happens when a client makes a connection and closes it *before* the server "accepts" the connection. It looks like Windows keeps the connection in the "accept" queue of the server socket and decides to return "lNetworkEvents == 0" when it notices the network event is for a socket in the "closed" state. The fix is to make sure we do *not* ignore socket events with "lNetworkEvents == 0" (in the FD_ACCEPT code path), because doing so leads us in a "blocked" state: 1) we don't clear our callback and 2) we don't issue another WSASelectEvent. So, instead of ignoring the event, we start a wait for the next FD_ACCEPT event. BUG=170595 Review URL: https://codereview.chromium.org/25686003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226781 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/tcp_socket_win.cc')
-rw-r--r--net/socket/tcp_socket_win.cc8
1 files changed, 8 insertions, 0 deletions
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc
index 7d76232..811af1c 100644
--- a/net/socket/tcp_socket_win.cc
+++ b/net/socket/tcp_socket_win.cc
@@ -742,6 +742,14 @@ void TCPSocketWin::OnObjectSignaled(HANDLE object) {
accept_address_ = NULL;
base::ResetAndReturn(&accept_callback_).Run(result);
}
+ } else {
+ // This happens when a client opens a connection and closes it before we
+ // have a chance to accept it.
+ DCHECK(ev.lNetworkEvents == 0);
+
+ // Start watching the next FD_ACCEPT event.
+ WSAEventSelect(socket_, accept_event_, FD_ACCEPT);
+ accept_watcher_.StartWatching(accept_event_, this);
}
}