diff options
author | Andrew Gerrand <adg@golang.org> | 2016-05-31 15:30:52 +1000 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2016-06-06 21:15:35 +0000 |
commit | a71af25401d68645ca23b2303ac6ae426739aa8b (patch) | |
tree | d2027527bc61811b92a3d4431889ee1ee30be5ac | |
parent | f9b4556de01710a964ffd0513eb7574a2d1fd62c (diff) | |
download | go-a71af25401d68645ca23b2303ac6ae426739aa8b.tar.gz go-a71af25401d68645ca23b2303ac6ae426739aa8b.zip |
time: warn about correct use of a Timer's Stop/Reset methods
Updates #14038
Fixes #14383
Change-Id: Icf6acb7c5d13ff1d3145084544c030a778482a38
Reviewed-on: https://go-review.googlesource.com/23575
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r-- | src/time/sleep.go | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/time/sleep.go b/src/time/sleep.go index 7661f7e54f..73114f5eec 100644 --- a/src/time/sleep.go +++ b/src/time/sleep.go @@ -54,6 +54,14 @@ type Timer struct { // expired or been stopped. // Stop does not close the channel, to prevent a read from the channel succeeding // incorrectly. +// +// To prevent the timer firing after a call to Stop, +// check the return value and drain the channel. For example: +// if !t.Stop() { +// <-t.C +// } +// This cannot be done concurrent to other receives from the Timer's +// channel. func (t *Timer) Stop() bool { if t.r.f == nil { panic("time: Stop called on uninitialized Timer") @@ -80,6 +88,20 @@ func NewTimer(d Duration) *Timer { // 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. +// +// To reuse an active timer, always call its Stop method first and—if it had +// expired—drain the value from its channel. For example: +// if !t.Stop() { +// <-t.C +// } +// t.Reset(d) +// This should not be done concurrent to other receives from the Timer's +// channel. +// +// Note that it is not possible to use Reset's return value correctly, as there +// is a race condition between draining the channel and the new timer expiring. +// Reset should always be used in concert with Stop, as described above. +// The return value exists to preserve compatibility with existing programs. func (t *Timer) Reset(d Duration) bool { if t.r.f == nil { panic("time: Reset called on uninitialized Timer") |