mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
os/signal: avoid race between Stop and receiving on channel
When Stop is called on a channel, wait until all signals have been delivered to the channel before returning. Use atomic operations in sigqueue to communicate more reliably between the os/signal goroutine and the signal handler. Fixes #14571 Change-Id: I6c5a9eea1cff85e37a34dffe96f4bb2699e12c6e Reviewed-on: https://go-review.googlesource.com/46003 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
3785457c76
commit
8ec7a39fec
4 changed files with 221 additions and 9 deletions
|
|
@ -110,6 +110,26 @@ func signal_recv() string {
|
|||
}
|
||||
}
|
||||
|
||||
// signalWaitUntilIdle waits until the signal delivery mechanism is idle.
|
||||
// This is used to ensure that we do not drop a signal notification due
|
||||
// to a race between disabling a signal and receiving a signal.
|
||||
// This assumes that signal delivery has already been disabled for
|
||||
// the signal(s) in question, and here we are just waiting to make sure
|
||||
// that all the signals have been delivered to the user channels
|
||||
// by the os/signal package.
|
||||
//go:linkname signalWaitUntilIdle os/signal.signalWaitUntilIdle
|
||||
func signalWaitUntilIdle() {
|
||||
for {
|
||||
lock(&sig.lock)
|
||||
sleeping := sig.sleeping
|
||||
unlock(&sig.lock)
|
||||
if sleeping {
|
||||
return
|
||||
}
|
||||
Gosched()
|
||||
}
|
||||
}
|
||||
|
||||
// Must only be called from a single goroutine at a time.
|
||||
//go:linkname signal_enable os/signal.signal_enable
|
||||
func signal_enable(s uint32) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue