From c292c68cbacdef317bf8d44abc3a454772d2581a Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 5 May 2016 15:41:10 -0400 Subject: [PATCH] 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. --- signal.go | 10 +++++++--- signalsigterm.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 signalsigterm.go diff --git a/signal.go b/signal.go index c904d8b..891f05e 100644 --- a/signal.go +++ b/signal.go @@ -22,6 +22,10 @@ var interruptHandlersDone = make(chan struct{}) 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 // internal component instead of a SIGINT. func simulateInterrupt() { @@ -49,8 +53,8 @@ func mainInterruptHandler() { for { select { - case <-interruptChannel: - log.Info("Received SIGINT (Ctrl+C). Shutting down...") + case sig := <-interruptChannel: + log.Infof("Received signal (%s). Shutting down...", sig) invokeCallbacks() return case <-simulateInterruptChannel: @@ -71,7 +75,7 @@ func addInterruptHandler(handler func()) { // all other callbacks and exits if not already done. if interruptChannel == nil { interruptChannel = make(chan os.Signal, 1) - signal.Notify(interruptChannel, os.Interrupt) + signal.Notify(interruptChannel, signals...) go mainInterruptHandler() } diff --git a/signalsigterm.go b/signalsigterm.go new file mode 100644 index 0000000..7aaa39a --- /dev/null +++ b/signalsigterm.go @@ -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} +}