aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gerrand <adg@golang.org>2016-05-31 15:30:52 +1000
committerAndrew Gerrand <adg@golang.org>2016-06-06 21:15:35 +0000
commita71af25401d68645ca23b2303ac6ae426739aa8b (patch)
treed2027527bc61811b92a3d4431889ee1ee30be5ac
parentf9b4556de01710a964ffd0513eb7574a2d1fd62c (diff)
downloadgo-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.go22
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")