mirror of
https://github.com/golang/go.git
synced 2026-02-07 03:15:05 +03:00
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>
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user