aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/netpoll.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/netpoll.go')
-rw-r--r--src/runtime/netpoll.go48
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))