From 60d437f99468906935f35e5c6fbd31c7228a1045 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 7 Feb 2020 10:49:33 -0800 Subject: [PATCH] runtime: avoid double notewakeup in netpoll stub code Otherwise we can see - goroutine 1 calls netpollBreak, the atomic.Cas succeeds, then suspends - goroutine 2 calls noteclear, sets netpollBroken to 0 - goroutine 3 calls netpollBreak, the atomic.Cas succeeds, calls notewakeup - goroutine 1 wakes up calls notewakeup, crashes due to double wakeup This doesn't happen on Plan 9 because it only runs one thread at a time. But Fuschia wants to use this code too. Change-Id: Ib636e4f327bb15e44a2c40fd681aae9a91073a30 Reviewed-on: https://go-review.googlesource.com/c/go/+/218537 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Michael Knyszek --- src/runtime/netpoll_stub.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/runtime/netpoll_stub.go b/src/runtime/netpoll_stub.go index fe45cfbd40..f86f2f6174 100644 --- a/src/runtime/netpoll_stub.go +++ b/src/runtime/netpoll_stub.go @@ -13,16 +13,23 @@ var netpollWaiters uint32 var netpollStubLock mutex var netpollNote note -var netpollBroken uint32 + +// netpollBroken, protected by netpollBrokenLock, avoids a double notewakeup. +var netpollBrokenLock mutex +var netpollBroken bool func netpollGenericInit() { atomic.Store(&netpollInited, 1) } func netpollBreak() { - if atomic.Cas(&netpollBroken, 0, 1) { + lock(&netpollBrokenLock) + broken := netpollBroken + netpollBroken = true + if !broken { notewakeup(&netpollNote) } + unlock(&netpollBrokenLock) } // Polls for ready network connections. @@ -34,8 +41,12 @@ func netpoll(delay int64) gList { // This lock ensures that only one goroutine tries to use // the note. It should normally be completely uncontended. lock(&netpollStubLock) + + lock(&netpollBrokenLock) noteclear(&netpollNote) - atomic.Store(&netpollBroken, 0) + netpollBroken = false + unlock(&netpollBrokenLock) + notetsleep(&netpollNote, delay) unlock(&netpollStubLock) } -- 2.48.1