mirror of
https://github.com/golang/go
synced 2024-11-22 06:04:39 -07:00
time: make tick.Stop a little more robust
R=r CC=golang-dev, jackpal https://golang.org/cl/186228
This commit is contained in:
parent
fe01d4c8a1
commit
1634b4236b
@ -24,12 +24,26 @@ package time
|
|||||||
// at intervals.
|
// at intervals.
|
||||||
type Ticker struct {
|
type Ticker struct {
|
||||||
C <-chan int64 // The channel on which the ticks are delivered.
|
C <-chan int64 // The channel on which the ticks are delivered.
|
||||||
|
done chan bool
|
||||||
ns int64
|
ns int64
|
||||||
shutdown bool
|
shutdown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop turns off a ticker. After Stop, no more ticks will be delivered.
|
// Stop turns off a ticker. After Stop, no more ticks will be sent.
|
||||||
func (t *Ticker) Stop() { t.shutdown = true }
|
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) {
|
func (t *Ticker) ticker(c chan<- int64) {
|
||||||
now := Nanoseconds()
|
now := Nanoseconds()
|
||||||
@ -47,13 +61,23 @@ func (t *Ticker) ticker(c chan<- int64) {
|
|||||||
when += t.ns
|
when += t.ns
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(when - now)
|
for !t.shutdown && when > now {
|
||||||
now = Nanoseconds()
|
// 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 {
|
if t.shutdown {
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
c <- now
|
c <- now
|
||||||
}
|
}
|
||||||
|
t.done <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tick is a convenience wrapper for NewTicker providing access to the ticking
|
// Tick is a convenience wrapper for NewTicker providing access to the ticking
|
||||||
@ -73,7 +97,7 @@ func NewTicker(ns int64) *Ticker {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
c := make(chan int64)
|
c := make(chan int64)
|
||||||
t := &Ticker{c, ns, false}
|
t := &Ticker{c, make(chan bool), ns, false}
|
||||||
go t.ticker(c)
|
go t.ticker(c)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user