Commit 68f3759e by Ian Lance Taylor

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
parent e3b6c052
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.
...@@ -85,6 +85,10 @@ func netpolldescriptor() uintptr { ...@@ -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) { ...@@ -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: ...@@ -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: ...@@ -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
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment