btcd: handle signal SIGTERM (#688)
When an OS reboots or shuts down, it sends all processes SIGTERM before sending SIGKILL. This allows btcd to do a proper shutdown which most importantly closes the database.
This commit is contained in:
parent
0d7f526600
commit
1a0e7452f3
2 changed files with 26 additions and 5 deletions
15
signal.go
15
signal.go
|
@ -16,6 +16,10 @@ var interruptChannel chan os.Signal
|
||||||
// to be invoked on SIGINT (Ctrl+C) signals.
|
// to be invoked on SIGINT (Ctrl+C) signals.
|
||||||
var addHandlerChannel = make(chan func())
|
var addHandlerChannel = make(chan func())
|
||||||
|
|
||||||
|
// signals defines the default signals to catch in order to do a proper
|
||||||
|
// shutdown.
|
||||||
|
var signals = []os.Signal{os.Interrupt}
|
||||||
|
|
||||||
// mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the
|
// mainInterruptHandler listens for SIGINT (Ctrl+C) signals on the
|
||||||
// interruptChannel and invokes the registered interruptCallbacks accordingly.
|
// interruptChannel and invokes the registered interruptCallbacks accordingly.
|
||||||
// It also listens for callback registration. It must be run as a goroutine.
|
// It also listens for callback registration. It must be run as a goroutine.
|
||||||
|
@ -32,16 +36,17 @@ func mainInterruptHandler() {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-interruptChannel:
|
case sig := <-interruptChannel:
|
||||||
// Ignore more than one shutdown signal.
|
// Ignore more than one shutdown signal.
|
||||||
if isShutdown {
|
if isShutdown {
|
||||||
btcdLog.Infof("Received SIGINT (Ctrl+C). " +
|
btcdLog.Infof("Received signal (%s). "+
|
||||||
"Already shutting down...")
|
"Already shutting down...", sig)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
isShutdown = true
|
isShutdown = true
|
||||||
btcdLog.Infof("Received SIGINT (Ctrl+C). Shutting down...")
|
btcdLog.Infof("Received signal (%s). Shutting down...",
|
||||||
|
sig)
|
||||||
|
|
||||||
// Run handlers in LIFO order.
|
// Run handlers in LIFO order.
|
||||||
for i := range interruptCallbacks {
|
for i := range interruptCallbacks {
|
||||||
|
@ -74,7 +79,7 @@ func addInterruptHandler(handler func()) {
|
||||||
// all other callbacks and exits if not already done.
|
// all other callbacks and exits if not already done.
|
||||||
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, signals...)
|
||||||
go mainInterruptHandler()
|
go mainInterruptHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
signalsigterm.go
Normal file
16
signalsigterm.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) 2016 The btcsuite developers
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
||||||
|
}
|
Loading…
Reference in a new issue