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