In #14383 (comment), @rsc said:
There is an argument for making
tr := time.NewTimer(0)
tr.Stop()
// There may or may not be a value in the channel now. But definitely
// one should not be added after we receive it.
select {
case <-tr.C:
default:
}
work, but it doesn't today, and we're certainly not going to do that for Go 1.7. Maybe early in Go 1.8 if someone wants to file a different bug.
As far as I can tell, no different bug was filed: the documentation for (*Timer).Stop still says:
|
// To ensure the channel is empty after a call to Stop, 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. |
and that behavior is still resulting in subtle bugs (
#27169). (Note that
@rsc himself assumed that a
select should work in this way in
#14038 (comment).)
I think we should tighten up the invariants of (*Timer).Stop to eliminate this subtlety.
CC @empijei @matttproud @the80srobot @ianlancetaylor
In #14383 (comment), @rsc said:
As far as I can tell, no different bug was filed: the documentation for
(*Timer).Stopstill says:go/src/time/sleep.go
Lines 57 to 66 in 7d2473d
and that behavior is still resulting in subtle bugs (#27169). (Note that @rsc himself assumed that a
selectshould work in this way in #14038 (comment).)I think we should tighten up the invariants of
(*Timer).Stopto eliminate this subtlety.CC @empijei @matttproud @the80srobot @ianlancetaylor