From f19f31f2e7c136a8dae03cbfe4f8ebbb8b54569b Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Fri, 19 Jan 2024 16:51:24 -0500 Subject: [PATCH] net: work around runtime scheduler starvation on js and wasip1 Fixes #65177. Updates #65178. Updates #64321. Change-Id: I698fd3b688c7dfbde692eb7c29cbdafc89e7ca32 Cq-Include-Trybots: luci.golang.try:gotip-js-wasm,gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero Reviewed-on: https://go-review.googlesource.com/c/go/+/557037 Auto-Submit: Bryan Mills LUCI-TryBot-Result: Go LUCI Reviewed-by: Damien Neil --- src/net/net_fake.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/net/net_fake.go b/src/net/net_fake.go index 6b6fdc728e..525ff32296 100644 --- a/src/net/net_fake.go +++ b/src/net/net_fake.go @@ -14,6 +14,7 @@ import ( "errors" "io" "os" + "runtime" "sync" "sync/atomic" "syscall" @@ -513,6 +514,15 @@ func (pq *packetQueue) send(dt *deadlineTimer, b []byte, from sockaddr, block bo if !block { full = pq.full } + + // Before we check dt.expired, yield to other goroutines. + // This may help to prevent starvation of the goroutine that runs the + // deadlineTimer's time.After callback. + // + // TODO(#65178): Remove this when the runtime scheduler no longer starves + // runnable goroutines. + runtime.Gosched() + select { case <-dt.expired: return 0, os.ErrDeadlineExceeded @@ -563,6 +573,15 @@ func (pq *packetQueue) recvfrom(dt *deadlineTimer, b []byte, wholePacket bool, c // (Without this, TestZeroByteRead deadlocks.) empty = pq.empty } + + // Before we check dt.expired, yield to other goroutines. + // This may help to prevent starvation of the goroutine that runs the + // deadlineTimer's time.After callback. + // + // TODO(#65178): Remove this when the runtime scheduler no longer starves + // runnable goroutines. + runtime.Gosched() + select { case <-dt.expired: return 0, nil, os.ErrDeadlineExceeded