diff options
Diffstat (limited to 'src/pkg/time/sleep.go')
-rw-r--r-- | src/pkg/time/sleep.go | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/pkg/time/sleep.go b/src/pkg/time/sleep.go index 27820b0ea..591fa27b0 100644 --- a/src/pkg/time/sleep.go +++ b/src/pkg/time/sleep.go @@ -18,10 +18,25 @@ type runtimeTimer struct { i int32 when int64 period int64 - f func(int64, interface{}) + f func(int64, interface{}) // NOTE: must not be closure arg interface{} } +// when is a helper function for setting the 'when' field of a runtimeTimer. +// It returns what the time will be, in nanoseconds, Duration d in the future. +// If d is negative, it is ignored. If the returned value would be less than +// zero because of an overflow, MaxInt64 is returned. +func when(d Duration) int64 { + if d <= 0 { + return nano() + } + t := nano() + int64(d) + if t < 0 { + t = 1<<63 - 1 // math.MaxInt64 + } + return t +} + func startTimer(*runtimeTimer) func stopTimer(*runtimeTimer) bool @@ -35,8 +50,10 @@ type Timer struct { // Stop prevents the Timer from firing. // It returns true if the call stops the timer, false if the timer has already -// expired or stopped. -func (t *Timer) Stop() (ok bool) { +// expired or been stopped. +// Stop does not close the channel, to prevent a read from the channel succeeding +// incorrectly. +func (t *Timer) Stop() bool { return stopTimer(&t.r) } @@ -47,7 +64,7 @@ func NewTimer(d Duration) *Timer { t := &Timer{ C: c, r: runtimeTimer{ - when: nano() + int64(d), + when: when(d), f: sendTime, arg: c, }, @@ -56,6 +73,17 @@ func NewTimer(d Duration) *Timer { return t } +// Reset changes the timer to expire after duration d. +// It returns true if the timer had been active, false if the timer had +// expired or been stopped. +func (t *Timer) Reset(d Duration) bool { + w := when(d) + active := stopTimer(&t.r) + t.r.when = w + startTimer(&t.r) + return active +} + func sendTime(now int64, c interface{}) { // Non-blocking send of time on c. // Used in NewTimer, it cannot block anyway (buffer). @@ -81,7 +109,7 @@ func After(d Duration) <-chan Time { func AfterFunc(d Duration, f func()) *Timer { t := &Timer{ r: runtimeTimer{ - when: nano() + int64(d), + when: when(d), f: goFunc, arg: f, }, |