Russ Cox | c7bab46 | 2008-12-03 16:40:00 -0800 | [diff] [blame] | 1 | // Copyright 2009 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package time |
| 6 | |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 7 | import "errors" |
Rob Pike | fbb7029 | 2009-09-23 13:02:14 -0700 | [diff] [blame] | 8 | |
| 9 | // A Ticker holds a synchronous channel that delivers `ticks' of a clock |
| 10 | // at intervals. |
| 11 | type Ticker struct { |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 12 | C <-chan Time // The channel on which the ticks are delivered. |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 13 | r runtimeTimer |
Rob Pike | fbb7029 | 2009-09-23 13:02:14 -0700 | [diff] [blame] | 14 | } |
| 15 | |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 16 | // NewTicker returns a new Ticker containing a channel that will send the |
| 17 | // time, in nanoseconds, with a period specified by the duration argument. |
| 18 | // It adjusts the intervals or drops ticks to make up for slow receivers. |
| 19 | // The duration d must be greater than zero; if not, NewTicker will panic. |
| 20 | func NewTicker(d Duration) *Ticker { |
| 21 | if d <= 0 { |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 22 | panic(errors.New("non-positive interval for NewTicker")) |
Russ Cox | 6478df1 | 2008-12-08 17:45:50 -0800 | [diff] [blame] | 23 | } |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 24 | // Give the channel a 1-element time buffer. |
| 25 | // If the client falls behind while reading, we drop ticks |
| 26 | // on the floor until the client catches up. |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 27 | c := make(chan Time, 1) |
Rob Pike | 2ef0914 | 2010-12-13 13:52:19 -0800 | [diff] [blame] | 28 | t := &Ticker{ |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 29 | C: c, |
| 30 | r: runtimeTimer{ |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 31 | when: nano() + int64(d), |
| 32 | period: int64(d), |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 33 | f: sendTime, |
| 34 | arg: c, |
| 35 | }, |
Rob Pike | 2ef0914 | 2010-12-13 13:52:19 -0800 | [diff] [blame] | 36 | } |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 37 | startTimer(&t.r) |
Robert Griesemer | 45ca9f7 | 2009-12-15 15:41:46 -0800 | [diff] [blame] | 38 | return t |
Russ Cox | c7bab46 | 2008-12-03 16:40:00 -0800 | [diff] [blame] | 39 | } |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 40 | |
| 41 | // Stop turns off a ticker. After Stop, no more ticks will be sent. |
| 42 | func (t *Ticker) Stop() { |
| 43 | stopTimer(&t.r) |
| 44 | } |
| 45 | |
| 46 | // Tick is a convenience wrapper for NewTicker providing access to the ticking |
| 47 | // channel only. Useful for clients that have no need to shut down the ticker. |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 48 | func Tick(d Duration) <-chan Time { |
| 49 | if d <= 0 { |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 50 | return nil |
| 51 | } |
Russ Cox | efe3d35 | 2011-11-30 11:59:44 -0500 | [diff] [blame^] | 52 | return NewTicker(d).C |
Russ Cox | 3b86026 | 2011-11-09 15:17:05 -0500 | [diff] [blame] | 53 | } |