]> Cypherpunks repositories - gostls13.git/commitdiff
time: make tick.Stop a little more robust
authorRuss Cox <rsc@golang.org>
Wed, 20 Jan 2010 01:46:21 +0000 (17:46 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 20 Jan 2010 01:46:21 +0000 (17:46 -0800)
R=r
CC=golang-dev, jackpal
https://golang.org/cl/186228

src/pkg/time/tick.go

index a37e8ea4c46ff3c4a8de420cc7043c967ff3f409..98576dfe3063b65de57e21e39f3743867d9ad68c 100644 (file)
@@ -24,12 +24,26 @@ package time
 // at intervals.
 type Ticker struct {
        C        <-chan int64 // The channel on which the ticks are delivered.
+       done     chan bool
        ns       int64
        shutdown bool
 }
 
-// Stop turns off a ticker.  After Stop, no more ticks will be delivered.
-func (t *Ticker) Stop() { t.shutdown = true }
+// Stop turns off a ticker.  After Stop, no more ticks will be sent.
+func (t *Ticker) Stop() {
+       t.shutdown = true
+       go t.drain()
+}
+
+func (t *Ticker) drain() {
+       for {
+               select {
+               case <-t.C:
+               case <-t.done:
+                       return
+               }
+       }
+}
 
 func (t *Ticker) ticker(c chan<- int64) {
        now := Nanoseconds()
@@ -47,13 +61,23 @@ func (t *Ticker) ticker(c chan<- int64) {
                        when += t.ns
                }
 
-               Sleep(when - now)
-               now = Nanoseconds()
+               for !t.shutdown && when > now {
+                       // limit individual sleeps so that stopped
+                       // long-term tickers don't pile up.
+                       const maxSleep = 1e9
+                       if when-now > maxSleep {
+                               Sleep(maxSleep)
+                       } else {
+                               Sleep(when - now)
+                       }
+                       now = Nanoseconds()
+               }
                if t.shutdown {
-                       return
+                       break
                }
                c <- now
        }
+       t.done <- true
 }
 
 // Tick is a convenience wrapper for NewTicker providing access to the ticking
@@ -73,7 +97,7 @@ func NewTicker(ns int64) *Ticker {
                return nil
        }
        c := make(chan int64)
-       t := &Ticker{c, ns, false}
+       t := &Ticker{c, make(chan bool), ns, false}
        go t.ticker(c)
        return t
 }