aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/export_unix_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-11-07 21:08:48 -0800
committerIan Lance Taylor <iant@golang.org>2019-11-12 05:35:33 +0000
commit99957b6930c76b683dbca1ff4bcdd56e59b1e035 (patch)
tree48e93149df7e0b683450a9be932a58a1c56da8ab /src/runtime/export_unix_test.go
parentd22b5735e74c1e5905d1574853cb9a9f48da1afe (diff)
downloadgo-99957b6930c76b683dbca1ff4bcdd56e59b1e035.tar.gz
go-99957b6930c76b683dbca1ff4bcdd56e59b1e035.zip
runtime: use pipe rather than note in TestSignalM
At least on Darwin notewakeup is not async-signal-safe. Fixes #35276 Change-Id: I1d7523715e8e77dbd7f21d9b1ed131e52d46cc41 Reviewed-on: https://go-review.googlesource.com/c/go/+/206078 Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/export_unix_test.go')
-rw-r--r--src/runtime/export_unix_test.go35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/runtime/export_unix_test.go b/src/runtime/export_unix_test.go
index 375513337e..621488eaba 100644
--- a/src/runtime/export_unix_test.go
+++ b/src/runtime/export_unix_test.go
@@ -6,6 +6,8 @@
package runtime
+import "unsafe"
+
var NonblockingPipe = nonblockingPipe
var Pipe = pipe
var SetNonblock = setNonblock
@@ -26,33 +28,45 @@ func Sigisblocked(i int) bool {
type M = m
var waitForSigusr1 struct {
- park note
- mID int64
+ rdpipe int32
+ wrpipe int32
+ mID int64
}
// WaitForSigusr1 blocks until a SIGUSR1 is received. It calls ready
// when it is set up to receive SIGUSR1. The ready function should
-// cause a SIGUSR1 to be sent.
+// cause a SIGUSR1 to be sent. The r and w arguments are a pipe that
+// the signal handler can use to report when the signal is received.
//
// Once SIGUSR1 is received, it returns the ID of the current M and
-// the ID of the M the SIGUSR1 was received on. If no SIGUSR1 is
-// received for timeoutNS nanoseconds, it returns -1.
-func WaitForSigusr1(ready func(mp *M), timeoutNS int64) (int64, int64) {
+// the ID of the M the SIGUSR1 was received on. If the caller writes
+// a non-zero byte to w, WaitForSigusr1 returns immediately with -1, -1.
+func WaitForSigusr1(r, w int32, ready func(mp *M)) (int64, int64) {
lockOSThread()
// Make sure we can receive SIGUSR1.
unblocksig(_SIGUSR1)
+ waitForSigusr1.rdpipe = r
+ waitForSigusr1.wrpipe = w
+
mp := getg().m
testSigusr1 = waitForSigusr1Callback
ready(mp)
- ok := notetsleepg(&waitForSigusr1.park, timeoutNS)
- noteclear(&waitForSigusr1.park)
+
+ // Wait for the signal. We use a pipe rather than a note
+ // because write is always async-signal-safe.
+ entersyscallblock()
+ var b byte
+ read(waitForSigusr1.rdpipe, noescape(unsafe.Pointer(&b)), 1)
+ exitsyscall()
+
gotM := waitForSigusr1.mID
testSigusr1 = nil
unlockOSThread()
- if !ok {
+ if b != 0 {
+ // timeout signal from caller
return -1, -1
}
return mp.id, gotM
@@ -69,7 +83,8 @@ func waitForSigusr1Callback(gp *g) bool {
} else {
waitForSigusr1.mID = gp.m.id
}
- notewakeup(&waitForSigusr1.park)
+ b := byte(0)
+ write(uintptr(waitForSigusr1.wrpipe), noescape(unsafe.Pointer(&b)), 1)
return true
}