aboutsummaryrefslogtreecommitdiff
path: root/src/internal/poll
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2026-01-30 13:29:10 +0100
committerQuim Muntal <quimmuntal@gmail.com>2026-02-02 10:51:25 -0800
commit3b2a451cef467e42e41552cf490498d3bf39df29 (patch)
tree3e42e45cb98617476dad22420db492f5879c1d8f /src/internal/poll
parent6de7a19fea07bf8a9a54b7d9d3dc839fe2ea9d33 (diff)
downloadgo-3b2a451cef467e42e41552cf490498d3bf39df29.tar.xz
internal/poll: consolidate cancelIO logic into waitIO
This is a step towards deferring adding the handle to IOCP until the first IO operation. The main goal of this CL is to remove the fd.pollable() check in cancelIO. For #76391 Cq-Include-Trybots: luci.golang.try:gotip-windows-amd64-longtest,gotip-windows-amd64-race Change-Id: I76263ce12980297d88a5f6c514e4074dfee428cb Reviewed-on: https://go-review.googlesource.com/c/go/+/740540 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Damien Neil <dneil@google.com>
Diffstat (limited to 'src/internal/poll')
-rw-r--r--src/internal/poll/fd_windows.go38
1 files changed, 14 insertions, 24 deletions
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index edad656350..ef8050daf4 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -198,7 +198,8 @@ var operationPool = sync.Pool{
},
}
-// waitIO waits for the IO operation o to complete.
+// waitIO waits for the IO operation to complete,
+// handling cancellation if necessary.
func (fd *FD) waitIO(o *operation) error {
if fd.isBlocking {
panic("can't wait on blocking operations")
@@ -213,29 +214,24 @@ func (fd *FD) waitIO(o *operation) error {
// Wait for our request to complete.
err := fd.pd.wait(int(o.mode), fd.isFile)
switch err {
- case nil, ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
- // No other error is expected.
+ case nil:
+ // IO completed successfully.
+ case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
+ // IO interrupted by "close" or "timeout", cancel our request.
+ // ERROR_NOT_FOUND can be returned when the request succeded
+ // between the time wait returned and CancelIoEx was executed.
+ if err := syscall.CancelIoEx(fd.Sysfd, &o.o); err != nil && err != syscall.ERROR_NOT_FOUND {
+ // TODO(brainman): maybe do something else, but panic.
+ panic(err)
+ }
+ fd.pd.waitCanceled(int(o.mode))
default:
+ // No other error is expected.
panic("unexpected runtime.netpoll error: " + err.Error())
}
return err
}
-// cancelIO cancels the IO operation o and waits for it to complete.
-func (fd *FD) cancelIO(o *operation) {
- if !fd.pollable() {
- return
- }
- // Cancel our request.
- err := syscall.CancelIoEx(fd.Sysfd, &o.o)
- // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
- if err != nil && err != syscall.ERROR_NOT_FOUND {
- // TODO(brainman): maybe do something else, but panic.
- panic(err)
- }
- fd.pd.waitCanceled(int(o.mode))
-}
-
// pin pins ptr for the duration of the IO operation.
// If fd is in blocking mode, pin does nothing.
func (fd *FD) pin(mode int, ptr any) {
@@ -295,12 +291,6 @@ func (fd *FD) execIO(mode int, submit func(o *operation) (uint32, error)) (int,
// IO started asynchronously or completed synchronously but
// a sync notification is required. Wait for it to complete.
waitErr = fd.waitIO(o)
- if waitErr != nil {
- // IO interrupted by "close" or "timeout".
- fd.cancelIO(o)
- // We issued a cancellation request, but the IO operation may still succeeded
- // before the cancellation request runs.
- }
if fd.isFile {
err = windows.GetOverlappedResult(fd.Sysfd, &o.o, &qty, false)
} else {