aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_darwin.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-06-28 11:20:15 -0700
committerIan Lance Taylor <iant@golang.org>2019-06-30 05:48:31 +0000
commitc485e8b55918b3b37e6eab47036ab6f16fec226d (patch)
treed2c8dfa28092ff8c715c817a9e9574e076906669 /src/runtime/sys_darwin.go
parent623d653db7cd2287305347196f7f4742b6b1fb38 (diff)
downloadgo-c485e8b55918b3b37e6eab47036ab6f16fec226d.tar.gz
go-c485e8b55918b3b37e6eab47036ab6f16fec226d.zip
runtime: use a pipe to wake up signal_recv on Darwin
The implementation of semaphores, and therefore notes, used on Darwin is not async-signal-safe. The runtime has one case where a note needs to be woken up from a signal handler: the call to notewakeup in sigsend. That notewakeup call is only called on a single note, and it doesn't need the full functionality of notes: nothing ever does a timed wait on it. So change that one note to use a different implementation on Darwin, based on a pipe. This lets the wakeup code use the write call, which is async-signal-safe. Fixes #31264 Change-Id: If705072d7a961dd908ea9d639c8d12b222c64806 Reviewed-on: https://go-review.googlesource.com/c/go/+/184169 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/sys_darwin.go')
-rw-r--r--src/runtime/sys_darwin.go14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index b50d441d92..376f76dbc5 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -197,6 +197,13 @@ func read(fd int32, p unsafe.Pointer, n int32) int32 {
}
func read_trampoline()
+func pipe() (r, w int32, errno int32) {
+ var p [2]int32
+ errno = libcCall(unsafe.Pointer(funcPC(pipe_trampoline)), noescape(unsafe.Pointer(&p)))
+ return p[0], p[1], errno
+}
+func pipe_trampoline()
+
//go:nosplit
//go:cgo_unsafe_args
func closefd(fd int32) int32 {
@@ -395,6 +402,12 @@ func closeonexec(fd int32) {
fcntl(fd, _F_SETFD, _FD_CLOEXEC)
}
+//go:nosplit
+func setNonblock(fd int32) {
+ flags := fcntl(fd, _F_GETFL, 0)
+ fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
+}
+
// Tell the linker that the libc_* functions are to be found
// in a system library, with the libc_ prefix missing.
@@ -409,6 +422,7 @@ func closeonexec(fd int32) {
//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"