aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-08-01 16:05:17 -0700
committerIan Lance Taylor <iant@golang.org>2017-08-03 04:22:44 +0000
commitf396fa4285dd5def6d28ebedb4261cf89133bae1 (patch)
tree3d629857f8d665fe5b30bcd65968f98b5a0456ee
parent664cd26c89ec59cb6b686a9b3887ace7a76b0047 (diff)
downloadgo-f396fa4285dd5def6d28ebedb4261cf89133bae1.tar.gz
go-f396fa4285dd5def6d28ebedb4261cf89133bae1.zip
internal/poll: don't add non-sockets to runtime poller
Updates #21172 Change-Id: I0fec6e645328bbc85f3e47f4f71dd8d1d68c75ab Reviewed-on: https://go-review.googlesource.com/52551 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
-rw-r--r--src/internal/poll/fd_windows.go21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index 9f40886d08..655f9348c6 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -154,6 +154,10 @@ func (s *ioSrv) ProcessRemoteIO() {
// is available. Alternatively, it passes the request onto
// runtime netpoll and waits for completion or cancels request.
func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, error) {
+ if o.fd.pd.runtimeCtx == 0 {
+ return 0, errors.New("internal error: polling on unsupported descriptor type")
+ }
+
if !canCancelIO {
onceStartServer.Do(startServer)
}
@@ -315,8 +319,21 @@ func (fd *FD) Init(net string) (string, error) {
return "", errors.New("internal error: unknown network type " + net)
}
- if err := fd.pd.init(fd); err != nil {
- return "", err
+ if !fd.isFile && !fd.isConsole && !fd.isDir {
+ // Only call init for a network socket.
+ // This means that we don't add files to the runtime poller.
+ // Adding files to the runtime poller can confuse matters
+ // if the user is doing their own overlapped I/O.
+ // See issue #21172.
+ //
+ // In general the code below avoids calling the ExecIO
+ // method for non-network sockets. If some method does
+ // somehow call ExecIO, then ExecIO, and therefore the
+ // calling method, will return an error, because
+ // fd.pd.runtimeCtx will be 0.
+ if err := fd.pd.init(fd); err != nil {
+ return "", err
+ }
}
if hasLoadSetFileCompletionNotificationModes {
// We do not use events, so we can skip them always.