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 7 // A Ticker holds a channel that delivers “ticks” of a clock 8 // at intervals. 9 type Ticker struct { 10 C <-chan Time // The channel on which the ticks are delivered. 11 r runtimeTimer 12 } 13 14 // NewTicker returns a new Ticker containing a channel that will send 15 // the current time on the channel after each tick. The period of the 16 // ticks is specified by the duration argument. The ticker will adjust 17 // the time interval or drop ticks to make up for slow receivers. 18 // The duration d must be greater than zero; if not, NewTicker will 19 // panic. Stop the ticker to release associated resources. 20 func NewTicker(d Duration) *Ticker { 21 if d <= 0 { 22 panic("non-positive interval for NewTicker") 23 } 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. 27 c := make(chan Time, 1) 28 t := &Ticker{ 29 C: c, 30 r: runtimeTimer{ 31 when: when(d), 32 period: int64(d), 33 f: sendTime, 34 arg: c, 35 }, 36 } 37 startTimer(&t.r) 38 return t 39 } 40 41 // Stop turns off a ticker. After Stop, no more ticks will be sent. 42 // Stop does not close the channel, to prevent a concurrent goroutine 43 // reading from the channel from seeing an erroneous "tick". 44 func (t *Ticker) Stop() { 45 stopTimer(&t.r) 46 } 47 48 // Reset stops a ticker and resets its period to the specified duration. 49 // The next tick will arrive after the new period elapses. The duration d 50 // must be greater than zero; if not, Reset will panic. 51 func (t *Ticker) Reset(d Duration) { 52 if d <= 0 { 53 panic("non-positive interval for Ticker.Reset") 54 } 55 if t.r.f == nil { 56 panic("time: Reset called on uninitialized Ticker") 57 } 58 modTimer(&t.r, when(d), int64(d), t.r.f, t.r.arg, t.r.seq) 59 } 60 61 // Tick is a convenience wrapper for NewTicker providing access to the ticking 62 // channel only. While Tick is useful for clients that have no need to shut down 63 // the Ticker, be aware that without a way to shut it down the underlying 64 // Ticker cannot be recovered by the garbage collector; it "leaks". 65 // Unlike NewTicker, Tick will return nil if d <= 0. 66 func Tick(d Duration) <-chan Time { 67 if d <= 0 { 68 return nil 69 } 70 return NewTicker(d).C 71 } 72