2008-12-03 17:40:00 -07:00
|
|
|
// 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
|
|
|
|
|
2009-08-10 23:02:51 -06:00
|
|
|
// TODO(rsc): This implementation of Tick is a
|
2008-12-03 17:40:00 -07:00
|
|
|
// simple placeholder. Eventually, there will need to be
|
|
|
|
// a single central time server no matter how many tickers
|
2009-09-23 14:02:14 -06:00
|
|
|
// are active.
|
2008-12-03 17:40:00 -07:00
|
|
|
//
|
|
|
|
// Also, if timeouts become part of the select statement,
|
|
|
|
// perhaps the Ticker is just:
|
|
|
|
//
|
2008-12-19 04:05:37 -07:00
|
|
|
// func Ticker(ns int64, c chan int64) {
|
2008-12-03 17:40:00 -07:00
|
|
|
// for {
|
|
|
|
// select { timeout ns: }
|
2009-08-10 23:02:51 -06:00
|
|
|
// nsec, err := Nanoseconds();
|
2008-12-03 17:40:00 -07:00
|
|
|
// c <- nsec;
|
|
|
|
// }
|
|
|
|
|
2009-09-23 14:02:14 -06:00
|
|
|
|
|
|
|
// A Ticker holds a synchronous channel that delivers `ticks' of a clock
|
|
|
|
// at intervals.
|
|
|
|
type Ticker struct {
|
2009-10-07 12:55:06 -06:00
|
|
|
C <-chan int64; // The channel on which the ticks are delivered.
|
|
|
|
ns int64;
|
2009-09-23 14:02:14 -06:00
|
|
|
shutdown bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop turns off a ticker. After Stop, no more ticks will be delivered.
|
2009-11-06 15:24:38 -07:00
|
|
|
func (t *Ticker) Stop() { t.shutdown = true }
|
2009-09-23 14:02:14 -06:00
|
|
|
|
|
|
|
func (t *Ticker) ticker(c chan<- int64) {
|
2009-08-10 23:02:51 -06:00
|
|
|
now := Nanoseconds();
|
2008-12-08 18:45:50 -07:00
|
|
|
when := now;
|
2009-09-23 14:02:14 -06:00
|
|
|
for !t.shutdown {
|
|
|
|
when += t.ns; // next alarm
|
2008-12-09 11:57:55 -07:00
|
|
|
|
2008-12-08 18:45:50 -07:00
|
|
|
// if c <- now took too long, skip ahead
|
|
|
|
if when < now {
|
|
|
|
// one big step
|
2009-10-07 12:55:06 -06:00
|
|
|
when += (now-when) / t.ns * t.ns;
|
2008-12-08 18:45:50 -07:00
|
|
|
}
|
|
|
|
for when <= now {
|
|
|
|
// little steps until when > now
|
2009-10-07 12:55:06 -06:00
|
|
|
when += t.ns;
|
2008-12-08 18:45:50 -07:00
|
|
|
}
|
|
|
|
|
2009-10-07 12:55:06 -06:00
|
|
|
Sleep(when-now);
|
2009-08-10 23:02:51 -06:00
|
|
|
now = Nanoseconds();
|
2009-09-23 14:02:14 -06:00
|
|
|
if t.shutdown {
|
2009-09-14 18:20:29 -06:00
|
|
|
return;
|
|
|
|
}
|
2009-09-23 14:02:14 -06:00
|
|
|
c <- now;
|
2008-12-03 17:40:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-23 14:02:14 -06:00
|
|
|
// 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 {
|
2008-12-08 18:45:50 -07:00
|
|
|
if ns <= 0 {
|
2009-10-07 12:55:06 -06:00
|
|
|
return nil;
|
2008-12-08 18:45:50 -07:00
|
|
|
}
|
2009-09-23 14:02:14 -06:00
|
|
|
return NewTicker(ns).C;
|
2008-12-03 17:40:00 -07:00
|
|
|
}
|
|
|
|
|
2009-09-23 14:02:14 -06:00
|
|
|
// 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 {
|
2009-10-07 12:55:06 -06:00
|
|
|
return nil;
|
2009-09-23 14:02:14 -06:00
|
|
|
}
|
|
|
|
c := make(chan int64);
|
|
|
|
t := &Ticker{c, ns, false};
|
|
|
|
go t.ticker(c);
|
|
|
|
return t;
|
|
|
|
}
|