Commit 89cf67eb authored by Andrew Gerrand's avatar Andrew Gerrand

time: handle very large sleep durations

Fixes #4903.

R=golang-dev, daniel.morsing, dave, r
CC=golang-dev
https://golang.org/cl/7388056
parent 93158bf2
......@@ -22,6 +22,21 @@ type runtimeTimer struct {
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
......@@ -49,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,
},
......@@ -62,9 +77,9 @@ func NewTimer(d Duration) *Timer {
// 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 {
when := nano() + int64(d)
w := when(d)
active := stopTimer(&t.r)
t.r.when = when
t.r.when = w
startTimer(&t.r)
return active
}
......@@ -94,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,
},
......
......@@ -293,3 +293,23 @@ func TestReset(t *testing.T) {
}
t.Error(err)
}
// Test that sleeping for an interval so large it overflows does not
// result in a short sleep duration.
func TestOverflowSleep(t *testing.T) {
const timeout = 25 * Millisecond
const big = Duration(int64(1<<63 - 1))
select {
case <-After(big):
t.Fatalf("big timeout fired")
case <-After(timeout):
// OK
}
const neg = Duration(-1 << 63)
select {
case <-After(neg):
// OK
case <-After(timeout):
t.Fatalf("negative timeout didn't fire")
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment