File: trap.go

package info (click to toggle)
docker.io 28.5.2%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 69,048 kB
  • sloc: sh: 5,867; makefile: 863; ansic: 184; python: 162; asm: 159
file content (47 lines) | stat: -rw-r--r-- 1,216 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package trap

import (
	"context"
	"os"
	"os/signal"
	"syscall"

	"github.com/containerd/log"
)

const (
	// Immediately terminate the process when this many SIGINT or SIGTERM
	// signals are received.
	forceQuitCount = 3
)

// Trap sets up a simplified signal "trap", appropriate for common
// behavior expected from a vanilla unix command-line tool in general
// (and the Docker engine in particular).
//
// The first time a SIGINT or SIGTERM signal is received, `cleanup` is called in
// a new goroutine.
//
// If SIGINT or SIGTERM are received 3 times, the process is terminated
// immediately with an exit code of 128 + the signal number.
func Trap(cleanup func()) {
	c := make(chan os.Signal, forceQuitCount)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		var interruptCount int
		for sig := range c {
			log.G(context.TODO()).Infof("Processing signal '%v'", sig)
			if interruptCount < forceQuitCount {
				interruptCount++
				// Initiate the cleanup only once
				if interruptCount == 1 {
					go cleanup()
				}
				continue
			}

			log.G(context.TODO()).Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
			os.Exit(128 + int(sig.(syscall.Signal)))
		}
	}()
}