// 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; }