From 45f99d85e0d22a4414ebbdc41de843d88064f374 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 27 Mar 2020 17:37:37 -0700 Subject: [PATCH] runtime: avoid racing on pendingUpdates in AIX netpollBreak Instead of calling netpollwakeup, just do the write in netpollBreak. Use the same signaling we now use in other netpollBreak instances. Change-Id: I53a65c22862ecc8484aee91d0e1ffb21a9e62d8c Reviewed-on: https://go-review.googlesource.com/c/go/+/226199 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Bryan C. Mills --- src/runtime/netpoll_aix.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/runtime/netpoll_aix.go b/src/runtime/netpoll_aix.go index c936fbb70f..3c1f70874d 100644 --- a/src/runtime/netpoll_aix.go +++ b/src/runtime/netpoll_aix.go @@ -4,7 +4,10 @@ package runtime -import "unsafe" +import ( + "runtime/internal/atomic" + "unsafe" +) // This is based on the former libgo/runtime/netpoll_select.c implementation // except that it uses poll instead of select and is written in Go. @@ -41,6 +44,8 @@ var ( rdwake int32 wrwake int32 pendingUpdates int32 + + netpollWakeSig uintptr // used to avoid duplicate calls of netpollBreak ) func netpollinit() { @@ -130,7 +135,10 @@ func netpollarm(pd *pollDesc, mode int) { // netpollBreak interrupts a poll. func netpollBreak() { - netpollwakeup() + if atomic.Casuintptr(&netpollWakeSig, 0, 1) { + b := [1]byte{0} + write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1) + } } // netpoll checks for ready network connections. @@ -184,6 +192,7 @@ retry: var b [1]byte for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { } + atomic.Storeuintptr(&netpollWakeSig, 0) } // Still look at the other fds even if the mode may have // changed, as netpollBreak might have been called. -- 2.48.1