Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interrupt: fix send on closed #6147

Merged
merged 1 commit into from
Mar 28, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions cmd/ipfs/util/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,43 @@ import (
// IntrHandler helps set up an interrupt handler that can
// be cleanly shut down through the io.Closer interface.
type IntrHandler struct {
sig chan os.Signal
wg sync.WaitGroup
closing chan struct{}
wg sync.WaitGroup
}

func NewIntrHandler() *IntrHandler {
ih := &IntrHandler{}
ih.sig = make(chan os.Signal, 1)
return ih
return &IntrHandler{closing: make(chan struct{})}
}

func (ih *IntrHandler) Close() error {
close(ih.sig)
close(ih.closing)
ih.wg.Wait()
return nil
}

// Handle starts handling the given signals, and will call the handler
// callback function each time a signal is catched. The function is passed
// callback function each time a signal is caught. The function is passed
// the number of times the handler has been triggered in total, as
// well as the handler itself, so that the handling logic can use the
// handler's wait group to ensure clean shutdown when Close() is called.
func (ih *IntrHandler) Handle(handler func(count int, ih *IntrHandler), sigs ...os.Signal) {
signal.Notify(ih.sig, sigs...)
notify := make(chan os.Signal, 1)
signal.Notify(notify, sigs...)
ih.wg.Add(1)
go func() {
defer ih.wg.Done()
defer signal.Stop(notify)

count := 0
for range ih.sig {
count++
handler(count, ih)
for {
select {
case <-ih.closing:
return
case <-notify:
count++
handler(count, ih)
}
}
signal.Stop(ih.sig)
}()
}

Expand Down