summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/netpoll_stub.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/netpoll_stub.go')
-rw-r--r--libgo/go/runtime/netpoll_stub.go17
1 files changed, 14 insertions, 3 deletions
diff --git a/libgo/go/runtime/netpoll_stub.go b/libgo/go/runtime/netpoll_stub.go
index fe45cfbd400..f86f2f61748 100644
--- a/libgo/go/runtime/netpoll_stub.go
+++ b/libgo/go/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)
}