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  }