btcwallet: handle signal SIGTERM

When an OS reboots or shuts down, it sends all processes SIGTERM before
sending SIGKILL.  This allows btcwallet to do a proper shutdown which
most importantly closes the databases.
This commit is contained in:
David Hill 2016-05-05 15:41:10 -04:00
parent ce3bd39238
commit c292c68cba
2 changed files with 23 additions and 3 deletions

View file

@ -22,6 +22,10 @@ var interruptHandlersDone = make(chan struct{})
var simulateInterruptChannel = make(chan struct{}, 1) var simulateInterruptChannel = make(chan struct{}, 1)
// signals defines the signals that are handled to do a clean shutdown.
// Conditional compilation is used to also include SIGTERM on Unix.
var signals = []os.Signal{os.Interrupt}
// simulateInterrupt requests invoking the clean termination process by an // simulateInterrupt requests invoking the clean termination process by an
// internal component instead of a SIGINT. // internal component instead of a SIGINT.
func simulateInterrupt() { func simulateInterrupt() {
@ -49,8 +53,8 @@ func mainInterruptHandler() {
for { for {
select { select {
case <-interruptChannel: case sig := <-interruptChannel:
log.Info("Received SIGINT (Ctrl+C). Shutting down...") log.Infof("Received signal (%s). Shutting down...", sig)
invokeCallbacks() invokeCallbacks()
return return
case <-simulateInterruptChannel: case <-simulateInterruptChannel:
@ -71,7 +75,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
View 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}
}