diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-06-28 11:20:15 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-06-30 05:48:31 +0000 |
commit | c485e8b55918b3b37e6eab47036ab6f16fec226d (patch) | |
tree | d2c8dfa28092ff8c715c817a9e9574e076906669 /src/runtime/sys_darwin.go | |
parent | 623d653db7cd2287305347196f7f4742b6b1fb38 (diff) | |
download | go-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.go | 14 |
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" |