diff options
author | rpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-03 17:32:21 +0000 |
---|---|---|
committer | rpaquay@chromium.org <rpaquay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-03 17:32:21 +0000 |
commit | 79b168fdf65878b6c7f5a1ddc952272acfbca3bb (patch) | |
tree | 3f70850f634f94ad7edd0b315a33025062930511 /net/socket/tcp_socket_win.cc | |
parent | 110da40adb80643c8f2f9331fc037c3b826e9cdb (diff) | |
download | chromium_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.cc | 8 |
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); } } |