Skip to content

Commit

Permalink
pkg/watch: fix potential deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
abursavich committed Sep 15, 2014
1 parent 24b5b7e commit 435e0b7
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions pkg/watch/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ func (m *Mux) Watch() Interface {
id := m.nextWatcher
m.nextWatcher++
w := &muxWatcher{
result: make(chan Event),
id: id,
m: m,
result: make(chan Event),
stopped: make(chan struct{}),
id: id,
m: m,
}
m.watchers[id] = w
return w
Expand Down Expand Up @@ -119,15 +120,20 @@ func (m *Mux) distribute(event Event) {
m.lock.Lock()
defer m.lock.Unlock()
for _, w := range m.watchers {
w.result <- event
select {
case w.result <- event:
case <-w.stopped:
}
}
}

// muxWatcher handles a single watcher of a mux
type muxWatcher struct {
result chan Event
id int64
m *Mux
result chan Event
stopped chan struct{}
stop sync.Once
id int64
m *Mux
}

// ResultChan returns a channel to use for waiting on events.
Expand All @@ -137,5 +143,8 @@ func (mw *muxWatcher) ResultChan() <-chan Event {

// Stop stops watching and removes mw from its list.
func (mw *muxWatcher) Stop() {
mw.m.stopWatching(mw.id)
mw.stop.Do(func() {
close(mw.stopped)
mw.m.stopWatching(mw.id)
})
}

0 comments on commit 435e0b7

Please sign in to comment.