1package interrupthandler
2
3import (
4	"os"
5	"os/signal"
6	"sync"
7	"syscall"
8)
9
10type InterruptHandler struct {
11	interruptCount int
12	lock           *sync.Mutex
13	C              chan bool
14}
15
16func NewInterruptHandler() *InterruptHandler {
17	h := &InterruptHandler{
18		lock: &sync.Mutex{},
19		C:    make(chan bool, 0),
20	}
21
22	go h.handleInterrupt()
23	SwallowSigQuit()
24
25	return h
26}
27
28func (h *InterruptHandler) WasInterrupted() bool {
29	h.lock.Lock()
30	defer h.lock.Unlock()
31
32	return h.interruptCount > 0
33}
34
35func (h *InterruptHandler) handleInterrupt() {
36	c := make(chan os.Signal, 1)
37	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
38
39	<-c
40	signal.Stop(c)
41
42	h.lock.Lock()
43	h.interruptCount++
44	if h.interruptCount == 1 {
45		close(h.C)
46	} else if h.interruptCount > 5 {
47		os.Exit(1)
48	}
49	h.lock.Unlock()
50
51	go h.handleInterrupt()
52}
53