runtime: update netpoll_hurd.go for go1.14beta1 changes

Patch from Svante Signell.

Updates PR go/93468

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/216958
This commit is contained in:
Ian Lance Taylor 2020-01-29 16:36:25 -08:00
parent e3b6c052b6
commit 68f3759eff
2 changed files with 45 additions and 34 deletions

View File

@ -1,4 +1,4 @@
132e0e61d59aaa52f8fdb03a925300c1ced2a0f2 5b438257e6fe5f344ae2f973313f394cda85bf62
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -85,6 +85,10 @@ func netpolldescriptor() uintptr {
return uintptr(rdwake<<16 | wrwake) return uintptr(rdwake<<16 | wrwake)
} }
func netpollIsPollDescriptor(fd uintptr) bool {
return fd == uintptr(rdwake) || fd == uintptr(wrwake)
}
// netpollwakeup writes on wrwake to wakeup poll before any changes. // netpollwakeup writes on wrwake to wakeup poll before any changes.
func netpollwakeup() { func netpollwakeup() {
if pendingUpdates == 0 { if pendingUpdates == 0 {
@ -158,17 +162,32 @@ func netpollarm(pd *pollDesc, mode int) {
unlock(&mtxset) unlock(&mtxset)
} }
// polls for ready network connections // netpollBreak interrupts an epollwait.
// returns list of goroutines that become runnable func netpollBreak() {
netpollwakeup()
}
// netpoll checks for ready network connections.
// Returns list of goroutines that become runnable.
// delay < 0: blocks indefinitely
// delay == 0: does not block, just polls
// delay > 0: block for up to that many nanoseconds
//go:nowritebarrierrec //go:nowritebarrierrec
func netpoll(block bool) gList { func netpoll(delay int64) gList {
timeout := int32(0) timeout := int32(0)
if !block { if delay < 0 {
timeout = 0 timeout = 0
} else if delay == 0 {
// TODO: call poll with timeout == 0
return gList{} return gList{}
} } else if delay < 1e6 {
if pollVerbose { timeout = 1
println("*** netpoll", block) } else if delay < 1e15 {
timeout = int32(delay / 1e6)
} else {
// An arbitrary cap on how long to wait for a timer.
// 1e9 ms == ~11.5 days.
timeout = 1e9
} }
retry: retry:
lock(&mtxpoll) lock(&mtxpoll)
@ -176,40 +195,37 @@ retry:
pendingUpdates = 0 pendingUpdates = 0
unlock(&mtxpoll) unlock(&mtxpoll)
if pollVerbose {
println("*** netpoll before poll")
}
n := libc_poll(&pfds[0], int32(len(pfds)), timeout) n := libc_poll(&pfds[0], int32(len(pfds)), timeout)
if pollVerbose {
println("*** netpoll after poll", n)
}
if n < 0 { if n < 0 {
e := errno() e := errno()
if e != _EINTR { if e != _EINTR {
println("errno=", e, " len(pfds)=", len(pfds)) println("errno=", e, " len(pfds)=", len(pfds))
throw("poll failed") throw("poll failed")
} }
if pollVerbose {
println("*** poll failed")
}
unlock(&mtxset) unlock(&mtxset)
// If a timed sleep was interrupted, just return to
// recalculate how long we should sleep now.
if timeout > 0 {
return gList{}
}
goto retry goto retry
} }
// Check if some descriptors need to be changed // Check if some descriptors need to be changed
if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 { if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 {
var b [1]byte if delay != 0 {
for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { // A netpollwakeup could be picked up by a
if pollVerbose { // non-blocking poll. Only clear the wakeup
println("*** read 1 byte from pipe") // if blocking.
var b [1]byte
for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 {
} }
} }
// Do not look at the other fds in this case as the mode may have changed // Still look at the other fds even if the mode may have
// XXX only additions of flags are made, so maybe it is ok // changed, as netpollBreak might have been called.
unlock(&mtxset) n--
goto retry
} }
var toRun gList var toRun gList
for i := 0; i < len(pfds) && n > 0; i++ { for i := 1; i < len(pfds) && n > 0; i++ {
pfd := &pfds[i] pfd := &pfds[i]
var mode int32 var mode int32
@ -222,19 +238,14 @@ retry:
pfd.events &= ^_POLLOUT pfd.events &= ^_POLLOUT
} }
if mode != 0 { if mode != 0 {
if pollVerbose { pds[i].everr = false
println("*** netpollready i=", i, "revents=", pfd.revents, "events=", pfd.events, "pd=", pds[i]) if pfd.revents == _POLLERR {
pds[i].everr = true
} }
netpollready(&toRun, pds[i], mode) netpollready(&toRun, pds[i], mode)
n-- n--
} }
} }
unlock(&mtxset) unlock(&mtxset)
if block && toRun.empty() {
goto retry
}
if pollVerbose {
println("*** netpoll returning end")
}
return toRun return toRun
} }