]> Cypherpunks repositories - gostls13.git/commitdiff
time: warn about correct use of a Timer's Stop/Reset methods
authorAndrew Gerrand <adg@golang.org>
Tue, 31 May 2016 05:30:52 +0000 (15:30 +1000)
committerAndrew Gerrand <adg@golang.org>
Mon, 6 Jun 2016 21:15:35 +0000 (21:15 +0000)
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>

src/time/sleep.go

index 7661f7e54fc1302f8d1e1e5f2a1365127cbac8f8..73114f5eecda1b672c1388a09c4e63c13d142c25 100644 (file)
@@ -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")