From: Andrew Gerrand Date: Tue, 31 May 2016 05:30:52 +0000 (+1000) Subject: time: warn about correct use of a Timer's Stop/Reset methods X-Git-Tag: go1.7beta2~47 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a71af25401d68645ca23b2303ac6ae426739aa8b;p=gostls13.git 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 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- 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")