Skip to content
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

time: Timer.Reset documentation not accurate for AfterFunc timers #28100

Closed
bradfitz opened this issue Oct 9, 2018 · 7 comments
Closed

time: Timer.Reset documentation not accurate for AfterFunc timers #28100

bradfitz opened this issue Oct 9, 2018 · 7 comments
Labels
Documentation FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@bradfitz
Copy link
Contributor

bradfitz commented Oct 9, 2018

https://golang.org/pkg/time/#Timer.Reset says:

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:

And proceeds to give an example of proper usage of Reset.

But a Timer created by AfterFunc never sends on the channel.

We should probably say something about AfterFunc in the Timer.Reset docs.

/cc @dmitshur @ianlancetaylor

@bradfitz bradfitz added Documentation NeedsFix The path to resolution is known, but the work has not been done. labels Oct 9, 2018
@bradfitz bradfitz added this to the Go1.12 milestone Oct 9, 2018
@bradfitz
Copy link
Contributor Author

bradfitz commented Oct 9, 2018

The code makes it pretty clear a value is never sent on a channel, but here's a playground example:

https://play.golang.org/p/2OSQiHS4Zt5

Code:

func NewTimer(d Duration) *Timer {
        c := make(chan Time, 1)
        t := &Timer{    
                C: c,
                r: runtimeTimer{
                        when: when(d),
                        f:    sendTime,  // <<<<<<<<<<<<<<<<<<
                        arg:  c,
                },                      
        }                       
        startTimer(&t.r)
        return t        
}                       

vs

func AfterFunc(d Duration, f func()) *Timer {
        t := &Timer{
                r: runtimeTimer{
                        when: when(d),
                        f:    goFunc, // <<<<<<<<<<<<<<<<<<
                        arg:  f,
                },
        }       
        startTimer(&t.r)
        return t
}               

@bradfitz
Copy link
Contributor Author

bradfitz commented Oct 9, 2018

Context: review comments on https://go-review.googlesource.com/c/go/+/137335

@dmitshur
Copy link
Contributor

dmitshur commented Oct 9, 2018

We should probably say something about AfterFunc in the Timer.Reset docs.

Agreed.

My parsing of the Reset documentation was that the f parameter to AfterFunc being executed is equivalent to a value being received from t.C, and I figured that t.C gets received internally by AfterFunc to call f (or an equivalent mechanism).

However, it'd be great to be explicit and more accurate.

@ianlancetaylor
Copy link
Contributor

If Reset returns true, the function passed to AfterFunc will not be called. If Reset returns false, the function has already been called in a separate goroutine.

@andybons andybons modified the milestones: Go1.12, Go1.13 Feb 12, 2019
@andybons andybons modified the milestones: Go1.13, Go1.14 Jul 8, 2019
@rsc rsc modified the milestones: Go1.14, Backlog Oct 9, 2019
@mlowicki
Copy link
Contributor

What about changing:

Reset should be invoked only on stopped or expired timers with drained channels.

to:

For a timer created with NewTimer, Reset should be invoked only on stopped or expired timers with drained channels.

?

@ianlancetaylor
Copy link
Contributor

If we're going to change something we may as well explain what happens with a timer created by time.AfterFunc.

@gopherbot
Copy link

Change https://golang.org/cl/285632 mentions this issue: time: clarify Timer.Reset behavior on AfterFunc Timers

@golang golang locked and limited conversation to collaborators Jan 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

9 participants