github.com/btcsuite/btcd@v0.24.0/signal.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "os" 9 "os/signal" 10 ) 11 12 // shutdownRequestChannel is used to initiate shutdown from one of the 13 // subsystems using the same code paths as when an interrupt signal is received. 14 var shutdownRequestChannel = make(chan struct{}) 15 16 // interruptSignals defines the default signals to catch in order to do a proper 17 // shutdown. This may be modified during init depending on the platform. 18 var interruptSignals = []os.Signal{os.Interrupt} 19 20 // interruptListener listens for OS Signals such as SIGINT (Ctrl+C) and shutdown 21 // requests from shutdownRequestChannel. It returns a channel that is closed 22 // when either signal is received. 23 func interruptListener() <-chan struct{} { 24 c := make(chan struct{}) 25 go func() { 26 interruptChannel := make(chan os.Signal, 1) 27 signal.Notify(interruptChannel, interruptSignals...) 28 29 // Listen for initial shutdown signal and close the returned 30 // channel to notify the caller. 31 select { 32 case sig := <-interruptChannel: 33 btcdLog.Infof("Received signal (%s). Shutting down...", 34 sig) 35 36 case <-shutdownRequestChannel: 37 btcdLog.Info("Shutdown requested. Shutting down...") 38 } 39 close(c) 40 41 // Listen for repeated signals and display a message so the user 42 // knows the shutdown is in progress and the process is not 43 // hung. 44 for { 45 select { 46 case sig := <-interruptChannel: 47 btcdLog.Infof("Received signal (%s). Already "+ 48 "shutting down...", sig) 49 50 case <-shutdownRequestChannel: 51 btcdLog.Info("Shutdown requested. Already " + 52 "shutting down...") 53 } 54 } 55 }() 56 57 return c 58 } 59 60 // interruptRequested returns true when the channel returned by 61 // interruptListener was closed. This simplifies early shutdown slightly since 62 // the caller can just use an if statement instead of a select. 63 func interruptRequested(interrupted <-chan struct{}) bool { 64 select { 65 case <-interrupted: 66 return true 67 default: 68 } 69 70 return false 71 }