decred.org/dcrdex@v1.0.5/client/cmd/bwctl/signal.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package main
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"os/signal"
    11  )
    12  
    13  // shutdownSignaled is closed whenever shutdown is invoked through an interrupt
    14  // signal. Any contexts created using withShutdownChannel are cancelled when
    15  // this is closed.
    16  var shutdownSignaled = make(chan struct{})
    17  
    18  // WithShutdownCancel creates a copy of a context that is cancelled whenever
    19  // shutdown is invoked through an interrupt signal.
    20  func withShutdownCancel(ctx context.Context) context.Context {
    21  	ctx, cancel := context.WithCancel(ctx)
    22  	go func() {
    23  		<-shutdownSignaled
    24  		cancel()
    25  	}()
    26  	return ctx
    27  }
    28  
    29  // ShutdownListener listens for shutdown requests and cancels all contexts
    30  // created from withShutdownCancel. This function never returns and is intended
    31  // to be spawned in a new goroutine.
    32  func shutdownListener() {
    33  	interruptChannel := make(chan os.Signal, 1)
    34  	// Only accept a single CTRL+C.
    35  	signal.Notify(interruptChannel, os.Interrupt)
    36  
    37  	// Listen for the initial shutdown signal
    38  	sig := <-interruptChannel
    39  	fmt.Printf("\nReceived signal (%s). Shutting down...\n", sig)
    40  
    41  	// Cancel all contexts created from withShutdownCancel.
    42  	close(shutdownSignaled)
    43  
    44  	// Listen for any more shutdown signals and log that shutdown has already
    45  	// been signaled.
    46  	for {
    47  		<-interruptChannel
    48  		fmt.Println("Shutdown signaled. Already shutting down...")
    49  	}
    50  }