From 68f3759eff5ee498b52490213650b42b1ad89f16 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 29 Jan 2020 16:36:25 -0800 Subject: [PATCH] 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 --- gcc/go/gofrontend/MERGE | 2 +- libgo/go/runtime/netpoll_hurd.go | 77 ++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 49312fa10f7..8d08e91211d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -132e0e61d59aaa52f8fdb03a925300c1ced2a0f2 +5b438257e6fe5f344ae2f973313f394cda85bf62 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/runtime/netpoll_hurd.go b/libgo/go/runtime/netpoll_hurd.go index b74ad2fe128..3d3fa4b76d3 100644 --- a/libgo/go/runtime/netpoll_hurd.go +++ b/libgo/go/runtime/netpoll_hurd.go @@ -85,6 +85,10 @@ func netpolldescriptor() uintptr { 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. func netpollwakeup() { if pendingUpdates == 0 { @@ -158,17 +162,32 @@ func netpollarm(pd *pollDesc, mode int) { unlock(&mtxset) } -// polls for ready network connections -// returns list of goroutines that become runnable +// netpollBreak interrupts an epollwait. +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 -func netpoll(block bool) gList { +func netpoll(delay int64) gList { timeout := int32(0) - if !block { + if delay < 0 { timeout = 0 + } else if delay == 0 { + // TODO: call poll with timeout == 0 return gList{} - } - if pollVerbose { - println("*** netpoll", block) + } else if delay < 1e6 { + timeout = 1 + } 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: lock(&mtxpoll) @@ -176,40 +195,37 @@ retry: pendingUpdates = 0 unlock(&mtxpoll) - if pollVerbose { - println("*** netpoll before poll") - } n := libc_poll(&pfds[0], int32(len(pfds)), timeout) - if pollVerbose { - println("*** netpoll after poll", n) - } if n < 0 { e := errno() if e != _EINTR { println("errno=", e, " len(pfds)=", len(pfds)) throw("poll failed") } - if pollVerbose { - println("*** poll failed") - } 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 } // Check if some descriptors need to be changed if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 { - var b [1]byte - for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { - if pollVerbose { - println("*** read 1 byte from pipe") + if delay != 0 { + // A netpollwakeup could be picked up by a + // non-blocking poll. Only clear the wakeup + // 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 - // XXX only additions of flags are made, so maybe it is ok - unlock(&mtxset) - goto retry + // Still look at the other fds even if the mode may have + // changed, as netpollBreak might have been called. + n-- } var toRun gList - for i := 0; i < len(pfds) && n > 0; i++ { + for i := 1; i < len(pfds) && n > 0; i++ { pfd := &pfds[i] var mode int32 @@ -222,19 +238,14 @@ retry: pfd.events &= ^_POLLOUT } if mode != 0 { - if pollVerbose { - println("*** netpollready i=", i, "revents=", pfd.revents, "events=", pfd.events, "pd=", pds[i]) + pds[i].everr = false + if pfd.revents == _POLLERR { + pds[i].everr = true } netpollready(&toRun, pds[i], mode) n-- } } unlock(&mtxset) - if block && toRun.empty() { - goto retry - } - if pollVerbose { - println("*** netpoll returning end") - } return toRun }