github.com/rawahars/moby@v24.0.4+incompatible/cmd/dockerd/trap/trap.go (about)

     1  package trap // import "github.com/docker/docker/cmd/dockerd/trap"
     2  
     3  import (
     4  	"os"
     5  	"os/signal"
     6  	"syscall"
     7  
     8  	"github.com/sirupsen/logrus"
     9  )
    10  
    11  const (
    12  	// Immediately terminate the process when this many SIGINT or SIGTERM
    13  	// signals are received.
    14  	forceQuitCount = 3
    15  )
    16  
    17  // Trap sets up a simplified signal "trap", appropriate for common
    18  // behavior expected from a vanilla unix command-line tool in general
    19  // (and the Docker engine in particular).
    20  //
    21  // The first time a SIGINT or SIGTERM signal is received, `cleanup` is called in
    22  // a new goroutine.
    23  //
    24  // If SIGINT or SIGTERM are received 3 times, the process is terminated
    25  // immediately with an exit code of 128 + the signal number.
    26  func Trap(cleanup func()) {
    27  	c := make(chan os.Signal, forceQuitCount)
    28  	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
    29  	go func() {
    30  		var interruptCount int
    31  		for sig := range c {
    32  			logrus.Infof("Processing signal '%v'", sig)
    33  			if interruptCount < forceQuitCount {
    34  				interruptCount++
    35  				// Initiate the cleanup only once
    36  				if interruptCount == 1 {
    37  					go cleanup()
    38  				}
    39  				continue
    40  			}
    41  
    42  			logrus.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
    43  			os.Exit(128 + int(sig.(syscall.Signal)))
    44  		}
    45  	}()
    46  }