-
Notifications
You must be signed in to change notification settings - Fork 18k
time: Timer.Stop documentation incorrect for Timer returned by AfterFunc #17600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think that for a |
I tested it and that is not always true. There seems to be a race. |
Interesting. I don't doubt you, but, looking at the code, I don't see how that is possible. Can you provide a test case? |
On my workstation the following reliably panics: package main
import (
"time"
)
func main() {
ch := make(chan struct{})
var timer *time.Timer
for i := 0; i < 1000000; i++ {
if timer != nil && !timer.Stop() {
ch = make(chan struct{})
}
timer = time.AfterFunc(0, func() {
close(ch)
})
}
} If you reduce the number of iterations to a small number, say 100, it rarely panics. |
I think there is a data race in that code. I think |
There is definitely a data race:
|
Yes, there is a data race. I am suggesting that we update the documentation because I don't think it is clear. I will propose some changes. |
CL https://golang.org/cl/33131 mentions this issue. |
The time.Timer.Stop() documentation states "To prevent the timer firing after a call to Stop, check the return value and drain the channel." This is incorrect because time.AfterFunc does not set time.Timer.C. nil channels always block, so if you follow the documentation, your code will block indefinitely.
Is there a way to be sure that a timer created with time.AfterFunc has fired if it is going to fire? Either way, this should be added to the documentation.
The text was updated successfully, but these errors were encountered: