Skip to content

Commit

Permalink
stmtdiagnostics: fix incorrect usage of timeutil.Timer
Browse files Browse the repository at this point in the history
The contract of `timeutil.Timer.Stop` is such that the timer can no
longer be used, and it was violated in `Registry.poll`. This is now
fixed by allocating a fresh timer after each `Stop` call.

Release note: None
  • Loading branch information
yuzefovich committed Feb 27, 2024
1 parent f267065 commit 196dfd5
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions pkg/sql/stmtdiagnostics/statement_diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,31 @@ func (r *Registry) Start(ctx context.Context, stopper *stop.Stopper) {

func (r *Registry) poll(ctx context.Context) {
var (
timer timeutil.Timer
timer *timeutil.Timer
// We need to store timer.C reference separately because timer.Stop()
// (called when polling is disabled) puts timer into the pool and
// prohibits further usage of stored timer.C.
timerC = timer.C
timerC <-chan time.Time
lastPoll time.Time
deadline time.Time
pollIntervalChanged = make(chan struct{}, 1)
maybeResetTimer = func() {
if interval := pollingInterval.Get(&r.st.SV); interval == 0 {
// Setting the interval to zero stops the polling.
timer.Stop()
if timer != nil {
timer.Stop()
timer = nil
}
// nil out the channel so that it'd block forever in the loop
// below (until the polling interval is changed).
timerC = nil
} else {
newDeadline := lastPoll.Add(interval)
if deadline.IsZero() || !deadline.Equal(newDeadline) {
deadline = newDeadline
if timer == nil {
timer = timeutil.NewTimer()
}
timer.Reset(timeutil.Until(deadline))
timerC = timer.C
}
Expand Down

0 comments on commit 196dfd5

Please sign in to comment.