From: Russ Cox Date: Tue, 18 Oct 2016 03:51:16 +0000 (-0400) Subject: time: revise Timer comments for Stop, Reset X-Git-Tag: go1.8beta1~800 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c999108723fb35cec3667f1fcd60933d2608becc;p=gostls13.git time: revise Timer comments for Stop, Reset The comments added for Go 1.7 are very close. Make explicit that they only apply if the timer is not known to have expired already. Fixes #14038. Change-Id: I6a38be7b2015e1571fc477e18444a8cee38aab29 Reviewed-on: https://go-review.googlesource.com/31350 Reviewed-by: Ian Lance Taylor Reviewed-by: Brad Fitzpatrick --- diff --git a/src/time/sleep.go b/src/time/sleep.go index 3868378227..8e5c8254f1 100644 --- a/src/time/sleep.go +++ b/src/time/sleep.go @@ -56,10 +56,13 @@ type Timer struct { // incorrectly. // // To prevent the timer firing after a call to Stop, -// check the return value and drain the channel. For example: +// check the return value and drain the channel. +// For example, assuming the program has not received from t.C already: +// // if !t.Stop() { // <-t.C // } +// // This cannot be done concurrent to other receives from the Timer's // channel. func (t *Timer) Stop() bool { @@ -89,18 +92,25 @@ func NewTimer(d Duration) *Timer { // 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: +// Resetting a timer must take care not to race with the send into t.C +// that happens when the current timer expires. +// If a program has already received a value from t.C, the timer is known +// to have expired, and t.Reset can be used directly. +// If a program has not yet received a value from t.C, however, +// the timer must be stopped and—if Stop reports that the timer expired +// before being stopped—the channel explicitly drained: +// // 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. +// Reset should always be invoked on stopped or expired channels, 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 {