blob: a37e8ea4c46ff3c4a8de420cc7043c967ff3f409 [file] [log] [blame]
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package time
// TODO(rsc): This implementation of Tick is a
// simple placeholder. Eventually, there will need to be
// a single central time server no matter how many tickers
// are active.
//
// Also, if timeouts become part of the select statement,
// perhaps the Ticker is just:
//
// func Ticker(ns int64, c chan int64) {
// for {
// select { timeout ns: }
// nsec, err := Nanoseconds();
// c <- nsec;
// }
// A Ticker holds a synchronous channel that delivers `ticks' of a clock
// at intervals.
type Ticker struct {
C <-chan int64 // The channel on which the ticks are delivered.
ns int64
shutdown bool
}
// Stop turns off a ticker. After Stop, no more ticks will be delivered.
func (t *Ticker) Stop() { t.shutdown = true }
func (t *Ticker) ticker(c chan<- int64) {
now := Nanoseconds()
when := now
for !t.shutdown {
when += t.ns // next alarm
// if c <- now took too long, skip ahead
if when < now {
// one big step
when += (now - when) / t.ns * t.ns
}
for when <= now {
// little steps until when > now
when += t.ns
}
Sleep(when - now)
now = Nanoseconds()
if t.shutdown {
return
}
c <- now
}
}
// Tick is a convenience wrapper for NewTicker providing access to the ticking
// channel only. Useful for clients that have no need to shut down the ticker.
func Tick(ns int64) <-chan int64 {
if ns <= 0 {
return nil
}
return NewTicker(ns).C
}
// Ticker returns a new Ticker containing a synchronous channel that will
// send the time, in nanoseconds, every ns nanoseconds. It adjusts the
// intervals to make up for pauses in delivery of the ticks.
func NewTicker(ns int64) *Ticker {
if ns <= 0 {
return nil
}
c := make(chan int64)
t := &Ticker{c, ns, false}
go t.ticker(c)
return t
}