@@ -154,6 +154,10 @@ func (s *ioSrv) ProcessRemoteIO() {
154
154
// is available. Alternatively, it passes the request onto
155
155
// runtime netpoll and waits for completion or cancels request.
156
156
func (s * ioSrv ) ExecIO (o * operation , submit func (o * operation ) error ) (int , error ) {
157
+ if o .fd .pd .runtimeCtx == 0 {
158
+ return 0 , errors .New ("internal error: polling on unsupported descriptor type" )
159
+ }
160
+
157
161
if ! canCancelIO {
158
162
onceStartServer .Do (startServer )
159
163
}
@@ -315,8 +319,21 @@ func (fd *FD) Init(net string) (string, error) {
315
319
return "" , errors .New ("internal error: unknown network type " + net )
316
320
}
317
321
318
- if err := fd .pd .init (fd ); err != nil {
319
- return "" , err
322
+ if ! fd .isFile && ! fd .isConsole && ! fd .isDir {
323
+ // Only call init for a network socket.
324
+ // This means that we don't add files to the runtime poller.
325
+ // Adding files to the runtime poller can confuse matters
326
+ // if the user is doing their own overlapped I/O.
327
+ // See issue #21172.
328
+ //
329
+ // In general the code below avoids calling the ExecIO
330
+ // method for non-network sockets. If some method does
331
+ // somehow call ExecIO, then ExecIO, and therefore the
332
+ // calling method, will return an error, because
333
+ // fd.pd.runtimeCtx will be 0.
334
+ if err := fd .pd .init (fd ); err != nil {
335
+ return "" , err
336
+ }
320
337
}
321
338
if hasLoadSetFileCompletionNotificationModes {
322
339
// We do not use events, so we can skip them always.
0 commit comments