From dd84b9d64fb98746a230cd24233ff50a562c39c9 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Fri, 28 Apr 2023 01:36:44 +0800 Subject: --- cli/internal/signals/signals.go | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 cli/internal/signals/signals.go (limited to 'cli/internal/signals') diff --git a/cli/internal/signals/signals.go b/cli/internal/signals/signals.go new file mode 100644 index 0000000..8634144 --- /dev/null +++ b/cli/internal/signals/signals.go @@ -0,0 +1,60 @@ +package signals + +import ( + "os" + "os/signal" + "sync" + "syscall" +) + +// Watcher watches for signals delivered to this process and provides +// the opportunity for turbo to run cleanup +type Watcher struct { + doneCh chan struct{} + closed bool + mu sync.Mutex + closers []func() +} + +// AddOnClose registers a cleanup handler to run when a signal is received +func (w *Watcher) AddOnClose(closer func()) { + w.mu.Lock() + defer w.mu.Unlock() + w.closers = append(w.closers, closer) +} + +// Close runs the cleanup handlers registered with this watcher +func (w *Watcher) Close() { + w.mu.Lock() + defer w.mu.Unlock() + if w.closed { + return + } + w.closed = true + for _, closer := range w.closers { + closer() + } + w.closers = nil + close(w.doneCh) +} + +// Done returns a channel that will be closed after all of the cleanup +// handlers have been run. +func (w *Watcher) Done() <-chan struct{} { + return w.doneCh +} + +// NewWatcher returns a new Watcher instance for watching signals. +func NewWatcher() *Watcher { + // TODO: platform specific signals to watch for? + signalCh := make(chan os.Signal, 1) + signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) + w := &Watcher{ + doneCh: make(chan struct{}), + } + go func() { + <-signalCh + w.Close() + }() + return w +} -- cgit v1.2.3-70-g09d2