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