Make the signal handling concurrent safe.
This commit is contained in:
parent
35c95f0a36
commit
c1b327c06a
1 changed files with 28 additions and 11 deletions
39
signal.go
39
signal.go
|
@ -12,9 +12,31 @@ import (
|
||||||
// interruptChannel is used to receive SIGINT (Ctrl+C) signals.
|
// interruptChannel is used to receive SIGINT (Ctrl+C) signals.
|
||||||
var interruptChannel chan os.Signal
|
var interruptChannel chan os.Signal
|
||||||
|
|
||||||
// interruptCallbacks is a list of callbacks to invoke when a SIGINT (Ctrl+C) is
|
// addHandlerChannel is used to add an interrupt handler to the list of handlers
|
||||||
// received.
|
// to be invoked on SIGINT (Ctrl+C) signals.
|
||||||
var interruptCallbacks []func()
|
var addHandlerChannel = make(chan func())
|
||||||
|
|
||||||
|
// mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the
|
||||||
|
// interruptChannel and invokes the registered interruptCallbacks accordingly.
|
||||||
|
// It also listens for callback registration. It must be run as a goroutine.
|
||||||
|
func mainInterruptHandler() {
|
||||||
|
// interruptCallbacks is a list of callbacks to invoke when a
|
||||||
|
// SIGINT (Ctrl+C) is received.
|
||||||
|
var interruptCallbacks []func()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-interruptChannel:
|
||||||
|
for _, callback := range interruptCallbacks {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
|
||||||
|
case handler := <-addHandlerChannel:
|
||||||
|
interruptCallbacks = append(interruptCallbacks, handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is
|
// addInterruptHandler adds a handler to call when a SIGINT (Ctrl+C) is
|
||||||
// received.
|
// received.
|
||||||
|
@ -24,13 +46,8 @@ func addInterruptHandler(handler func()) {
|
||||||
if interruptChannel == nil {
|
if interruptChannel == nil {
|
||||||
interruptChannel = make(chan os.Signal, 1)
|
interruptChannel = make(chan os.Signal, 1)
|
||||||
signal.Notify(interruptChannel, os.Interrupt)
|
signal.Notify(interruptChannel, os.Interrupt)
|
||||||
go func() {
|
go mainInterruptHandler()
|
||||||
<-interruptChannel
|
|
||||||
for _, callback := range interruptCallbacks {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
os.Exit(0)
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
interruptCallbacks = append(interruptCallbacks, handler)
|
|
||||||
|
addHandlerChannel <- handler
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue