diff options
Diffstat (limited to 'src/runtime/netpoll.go')
-rw-r--r-- | src/runtime/netpoll.go | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go index 3852598b7e..a332045342 100644 --- a/src/runtime/netpoll.go +++ b/src/runtime/netpoll.go @@ -33,6 +33,15 @@ import ( // func netpollIsPollDescriptor(fd uintptr) bool // Reports whether fd is a file descriptor used by the poller. +// Error codes returned by runtime_pollReset and runtime_pollWait. +// These must match the values in internal/poll/fd_poll_runtime.go. +const ( + pollNoError = 0 // no error + pollErrClosing = 1 // descriptor is closed + pollErrTimeout = 2 // I/O timeout + pollErrNotPollable = 3 // general error polling descriptor +) + // pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer // goroutines respectively. The semaphore can be in the following states: // pdReady - io readiness notification is pending; @@ -176,40 +185,47 @@ func (c *pollCache) free(pd *pollDesc) { unlock(&c.lock) } +// poll_runtime_pollReset, which is internal/poll.runtime_pollReset, +// prepares a descriptor for polling in mode, which is 'r' or 'w'. +// This returns an error code; the codes are defined above. //go:linkname poll_runtime_pollReset internal/poll.runtime_pollReset func poll_runtime_pollReset(pd *pollDesc, mode int) int { - err := netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode := netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } if mode == 'r' { pd.rg = 0 } else if mode == 'w' { pd.wg = 0 } - return 0 + return pollNoError } +// poll_runtime_pollWait, which is internal/poll.runtime_pollWait, +// waits for a descriptor to be ready for reading or writing, +// according to mode, which is 'r' or 'w'. +// This returns an error code; the codes are defined above. //go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait func poll_runtime_pollWait(pd *pollDesc, mode int) int { - err := netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode := netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } // As for now only Solaris, illumos, and AIX use level-triggered IO. if GOOS == "solaris" || GOOS == "illumos" || GOOS == "aix" { netpollarm(pd, mode) } for !netpollblock(pd, int32(mode), false) { - err = netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode = netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } // Can happen if timeout has fired and unblocked us, // but before we had a chance to run, timeout has been reset. // Pretend it has not happened and retry. } - return 0 + return pollNoError } //go:linkname poll_runtime_pollWaitCanceled internal/poll.runtime_pollWaitCanceled @@ -359,18 +375,18 @@ func netpollready(toRun *gList, pd *pollDesc, mode int32) { func netpollcheckerr(pd *pollDesc, mode int32) int { if pd.closing { - return 1 // ErrFileClosing or ErrNetClosing + return pollErrClosing } if (mode == 'r' && pd.rd < 0) || (mode == 'w' && pd.wd < 0) { - return 2 // ErrTimeout + return pollErrTimeout } // Report an event scanning error only on a read event. // An error on a write event will be captured in a subsequent // write call that is able to report a more specific error. if mode == 'r' && pd.everr { - return 3 // ErrNotPollable + return pollErrNotPollable } - return 0 + return pollNoError } func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool { @@ -447,7 +463,7 @@ func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g { new = pdReady } if atomic.Casuintptr(gpp, old, new) { - if old == pdReady || old == pdWait { + if old == pdWait { old = 0 } return (*g)(unsafe.Pointer(old)) |