recwatch: Do not send to channel if closed.

If we close the recwatcher right after it's opened, we might have
previously tried to send on the now closed channel.
This commit is contained in:
James Shubin
2017-02-05 18:57:08 -05:00
parent c247cd8fea
commit 3ac878db62

View File

@@ -51,6 +51,8 @@ type RecWatcher struct {
watcher *fsnotify.Watcher watcher *fsnotify.Watcher
watches map[string]struct{} watches map[string]struct{}
events chan Event // one channel for events and err... events chan Event // one channel for events and err...
closed bool // is the events channel closed?
mutex sync.Mutex // lock guarding the channel closing
once sync.Once once sync.Once
wg sync.WaitGroup wg sync.WaitGroup
exit chan struct{} exit chan struct{}
@@ -89,8 +91,14 @@ func (obj *RecWatcher) Init() error {
go func() { go func() {
if err := obj.Watch(); err != nil { if err := obj.Watch(); err != nil {
// we need this mutex, because if we Init and then Close
// immediately, this can send after closed which panics!
obj.mutex.Lock()
if !obj.closed {
obj.events <- Event{Error: err} obj.events <- Event{Error: err}
} }
obj.mutex.Unlock()
}
obj.Close() obj.Close()
}() }()
return nil return nil
@@ -124,7 +132,10 @@ func (obj *RecWatcher) close() {
// obj.events <- Event{Error: err} // obj.events <- Event{Error: err}
//} //}
} }
obj.mutex.Lock()
obj.closed = true
close(obj.events) close(obj.events)
obj.mutex.Unlock()
obj.closeErr = err // set the error obj.closeErr = err // set the error
} }