From 587ea81702eec81ba2e938af6d0c63467ff97116 Mon Sep 17 00:00:00 2001 From: fossisawesome-macbook-with-linux Date: Sun, 5 Jul 2026 00:21:50 -0400 Subject: [PATCH] fix(jukebox): stop leaking timers in IPC timeout wrappers time.After keeps its underlying timer alive until it fires, even when the select's other branch already won. Switch to time.NewTimer with a deferred Stop() so the timer is released immediately on the fast path. Addresses review feedback from gemini-code-assist on #5715. --- core/playback/mpv/track.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/playback/mpv/track.go b/core/playback/mpv/track.go index 4247bc050..1da5253b2 100644 --- a/core/playback/mpv/track.go +++ b/core/playback/mpv/track.go @@ -49,10 +49,12 @@ func (t *MpvTrack) getWithTimeout(property string) (interface{}, error) { val, err := t.Conn.Get(property) ch <- result{val, err} }() + timer := time.NewTimer(ipcTimeout) + defer timer.Stop() select { case res := <-ch: return res.val, res.err - case <-time.After(ipcTimeout): + case <-timer.C: return nil, errIPCTimeout } } @@ -62,10 +64,12 @@ func (t *MpvTrack) setWithTimeout(property string, value interface{}) error { go func() { ch <- t.Conn.Set(property, value) }() + timer := time.NewTimer(ipcTimeout) + defer timer.Stop() select { case err := <-ch: return err - case <-time.After(ipcTimeout): + case <-timer.C: return errIPCTimeout } } @@ -80,10 +84,12 @@ func (t *MpvTrack) callWithTimeout(args ...interface{}) (interface{}, error) { val, err := t.Conn.Call(args...) ch <- result{val, err} }() + timer := time.NewTimer(ipcTimeout) + defer timer.Stop() select { case res := <-ch: return res.val, res.err - case <-time.After(ipcTimeout): + case <-timer.C: return nil, errIPCTimeout } }