blob: e7a2ee2059867bd545d3f36d46f01efba3934155 [file] [log] [blame]
Russ Coxaa35aee2009-02-16 17:07:11 -08001// 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
5package time
6
Brad Fitzpatrick8159b692013-08-28 11:16:55 -07007// Sleep pauses the current goroutine for at least the duration d.
8// A negative or zero duration causes Sleep to return immediately.
Anthony Martin1cb254a2011-12-12 16:12:22 -05009func Sleep(d Duration)
10
Jay Weisskopf86c976f2014-02-24 10:57:46 -050011// runtimeNano returns the current value of the runtime clock in nanoseconds.
12func runtimeNano() int64
Russ Coxefe3d352011-11-30 11:59:44 -050013
Russ Cox3b860262011-11-09 15:17:05 -050014// Interface to timers implemented in package runtime.
15// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
16type runtimeTimer struct {
Dmitriy Vyukov9601aba2014-08-25 20:25:22 +040017 i int
Russ Cox3b860262011-11-09 15:17:05 -050018 when int64
19 period int64
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +040020 f func(interface{}, uintptr) // NOTE: must not be closure
Russ Cox3b860262011-11-09 15:17:05 -050021 arg interface{}
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +040022 seq uintptr
Roger Peppee2d15952010-12-06 14:19:30 -050023}
24
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110025// when is a helper function for setting the 'when' field of a runtimeTimer.
26// It returns what the time will be, in nanoseconds, Duration d in the future.
27// If d is negative, it is ignored. If the returned value would be less than
28// zero because of an overflow, MaxInt64 is returned.
29func when(d Duration) int64 {
30 if d <= 0 {
Jay Weisskopf86c976f2014-02-24 10:57:46 -050031 return runtimeNano()
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110032 }
Jay Weisskopf86c976f2014-02-24 10:57:46 -050033 t := runtimeNano() + int64(d)
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110034 if t < 0 {
35 t = 1<<63 - 1 // math.MaxInt64
36 }
37 return t
38}
39
Russ Cox3b860262011-11-09 15:17:05 -050040func startTimer(*runtimeTimer)
41func stopTimer(*runtimeTimer) bool
Roger Peppee2d15952010-12-06 14:19:30 -050042
Russ Cox3b860262011-11-09 15:17:05 -050043// The Timer type represents a single event.
44// When the Timer expires, the current time will be sent on C,
45// unless the Timer was created by AfterFunc.
Robert Griesemerbc89e8c2014-10-01 16:44:52 -070046// A Timer must be created with NewTimer or AfterFunc.
Russ Cox3b860262011-11-09 15:17:05 -050047type Timer struct {
Russ Coxefe3d352011-11-30 11:59:44 -050048 C <-chan Time
Russ Cox3b860262011-11-09 15:17:05 -050049 r runtimeTimer
50}
Roger Peppe2ae953b2011-01-25 12:25:48 -080051
Russ Cox3b860262011-11-09 15:17:05 -050052// Stop prevents the Timer from firing.
53// It returns true if the call stops the timer, false if the timer has already
Volker Dobler44ff17e2013-01-17 14:41:53 +110054// expired or been stopped.
Shenghou Ma48b739c2012-11-08 23:25:48 +080055// Stop does not close the channel, to prevent a read from the channel succeeding
56// incorrectly.
Volker Dobler44ff17e2013-01-17 14:41:53 +110057func (t *Timer) Stop() bool {
Brad Fitzpatrickab4af522014-10-21 13:26:40 +020058 if t.r.f == nil {
59 panic("time: Stop called on uninitialized Timer")
60 }
Russ Cox3b860262011-11-09 15:17:05 -050061 return stopTimer(&t.r)
Roger Peppee2d15952010-12-06 14:19:30 -050062}
63
Roger Peppe2ae953b2011-01-25 12:25:48 -080064// NewTimer creates a new Timer that will send
Sameer Ajmani1379d902012-01-07 20:53:53 -050065// the current time on its channel after at least duration d.
Russ Coxefe3d352011-11-30 11:59:44 -050066func NewTimer(d Duration) *Timer {
67 c := make(chan Time, 1)
Russ Cox3b860262011-11-09 15:17:05 -050068 t := &Timer{
69 C: c,
70 r: runtimeTimer{
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110071 when: when(d),
Russ Cox3b860262011-11-09 15:17:05 -050072 f: sendTime,
73 arg: c,
74 },
75 }
76 startTimer(&t.r)
77 return t
78}
79
Volker Dobler44ff17e2013-01-17 14:41:53 +110080// Reset changes the timer to expire after duration d.
81// It returns true if the timer had been active, false if the timer had
82// expired or been stopped.
83func (t *Timer) Reset(d Duration) bool {
Brad Fitzpatrickab4af522014-10-21 13:26:40 +020084 if t.r.f == nil {
85 panic("time: Reset called on uninitialized Timer")
86 }
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110087 w := when(d)
Volker Dobler44ff17e2013-01-17 14:41:53 +110088 active := stopTimer(&t.r)
Andrew Gerrand89cf67e2013-02-26 09:23:58 +110089 t.r.when = w
Volker Dobler44ff17e2013-01-17 14:41:53 +110090 startTimer(&t.r)
91 return active
92}
93
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +040094func sendTime(c interface{}, seq uintptr) {
Russ Cox3b860262011-11-09 15:17:05 -050095 // Non-blocking send of time on c.
96 // Used in NewTimer, it cannot block anyway (buffer).
97 // Used in NewTicker, dropping sends on the floor is
98 // the desired behavior when the reader gets behind,
99 // because the sends are periodic.
100 select {
Jay Weisskopf86c976f2014-02-24 10:57:46 -0500101 case c.(chan Time) <- Now():
Russ Cox3b860262011-11-09 15:17:05 -0500102 default:
103 }
Roger Peppe2ae953b2011-01-25 12:25:48 -0800104}
105
Russ Coxefe3d352011-11-30 11:59:44 -0500106// After waits for the duration to elapse and then sends the current time
Roger Peppee2d15952010-12-06 14:19:30 -0500107// on the returned channel.
Sameer Ajmani1379d902012-01-07 20:53:53 -0500108// It is equivalent to NewTimer(d).C.
Russ Coxefe3d352011-11-30 11:59:44 -0500109func After(d Duration) <-chan Time {
110 return NewTimer(d).C
Roger Peppe212e0742011-01-10 11:51:38 -0800111}
112
David Symonds2949f3b2011-12-08 15:42:44 +1100113// AfterFunc waits for the duration to elapse and then calls f
Roger Peppe2ae953b2011-01-25 12:25:48 -0800114// in its own goroutine. It returns a Timer that can
115// be used to cancel the call using its Stop method.
David Symonds2949f3b2011-12-08 15:42:44 +1100116func AfterFunc(d Duration, f func()) *Timer {
Russ Cox3b860262011-11-09 15:17:05 -0500117 t := &Timer{
118 r: runtimeTimer{
Andrew Gerrand89cf67e2013-02-26 09:23:58 +1100119 when: when(d),
Russ Cox3b860262011-11-09 15:17:05 -0500120 f: goFunc,
121 arg: f,
122 },
Roger Peppe2ae953b2011-01-25 12:25:48 -0800123 }
Russ Cox3b860262011-11-09 15:17:05 -0500124 startTimer(&t.r)
125 return t
Roger Peppe2ae953b2011-01-25 12:25:48 -0800126}
127
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +0400128func goFunc(arg interface{}, seq uintptr) {
Russ Cox3b860262011-11-09 15:17:05 -0500129 go arg.(func())()
Roger Peppee2d15952010-12-06 14:19:30 -0500130}