• Alex Brainman's avatar
    net: fix connection resets when closed on windows · fa3e4fc4
    Alex Brainman authored
    It is common to close network connection while another goroutine is
    blocked reading on another goroutine. This sequence corresponds to
    windows calls to WSARecv to start io, followed by GetQueuedCompletionStatus
    that blocks until io completes, and, finally, closesocket called from
    another thread. We were expecting that closesocket would unblock
    GetQueuedCompletionStatus, and it does, but not always
    (http://code.google.com/p/go/issues/detail?id=4170#c5). Also that sequence
    results in connection is being reset.
    
    This CL inserts CancelIo between GetQueuedCompletionStatus and closesocket,
    and waits for both WSARecv and GetQueuedCompletionStatus to complete before
    proceeding to closesocket.  This seems to fix both connection resets and
    issue 4170. It also makes windows code behave similar to unix version.
    
    Unfortunately, CancelIo needs to be called on the same thread as WSARecv.
    So we have to employ strategy we use for connections with deadlines to
    every connection now. It means, there are 2 unavoidable thread switches
    for every io. Some newer versions of windows have new CancelIoEx api that
    doesn't have these drawbacks, and this CL uses this capability when available.
    As time goes by, we should have less of CancelIo and more of CancelIoEx
    systems. Computers with CancelIoEx are also not affected by issue 4195 anymore.
    
    Fixes #3710
    Fixes #3746
    Fixes #4170
    Partial fix for issue 4195
    
    R=golang-dev, mikioh.mikioh, bradfitz, rsc
    CC=golang-dev
    https://golang.org/cl/6604072
    fa3e4fc4
fd_windows.go 13.9 KB