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 }