diff --git a/repeat_timer.go b/repeat_timer.go index f027af3f3..d7d9154d4 100644 --- a/repeat_timer.go +++ b/repeat_timer.go @@ -1,7 +1,9 @@ package common -import "time" -import "sync" +import ( + "sync" + "time" +) /* RepeatTimer repeatedly sends a struct{}{} to .Ch after each "dur" period. @@ -15,7 +17,7 @@ type RepeatTimer struct { name string ticker *time.Ticker quit chan struct{} - done chan struct{} + wg *sync.WaitGroup dur time.Duration } @@ -24,10 +26,11 @@ func NewRepeatTimer(name string, dur time.Duration) *RepeatTimer { Ch: make(chan time.Time), ticker: time.NewTicker(dur), quit: make(chan struct{}), - done: make(chan struct{}), + wg: new(sync.WaitGroup), name: name, dur: dur, } + t.wg.Add(1) go t.fireRoutine(t.ticker) return t } @@ -39,7 +42,7 @@ func (t *RepeatTimer) fireRoutine(ticker *time.Ticker) { t.Ch <- t_ case <-t.quit: // needed so we know when we can reset t.quit - t.done <- struct{}{} + t.wg.Done() return } } @@ -54,6 +57,7 @@ func (t *RepeatTimer) Reset() { t.ticker = time.NewTicker(t.dur) t.quit = make(chan struct{}) + t.wg.Add(1) go t.fireRoutine(t.ticker) } @@ -69,8 +73,13 @@ func (t *RepeatTimer) Stop() bool { exists := t.ticker != nil if exists { t.ticker.Stop() // does not close the channel + select { + case <-t.Ch: + // read off channel if there's anything there + default: + } close(t.quit) - <-t.done + t.wg.Wait() // must wait for quit to close else we race Reset t.ticker = nil } return exists