@@ -21,6 +21,7 @@ import (
2121 "strconv"
2222 "strings"
2323 "sync"
24+ "sync/atomic"
2425
2526 "github.com/gin-gonic/gin"
2627)
@@ -94,7 +95,7 @@ func (jellyfinHandler *JellyfinHandler) GetImageCacheRegexp() *regexp.Regexp {
9495 return constants .JellyfinRegexp .Cache .Image
9596}
9697
97- func (JellyfinHandler ) GetSubtitleCacheRegexp () * regexp.Regexp {
98+ func (* JellyfinHandler ) GetSubtitleCacheRegexp () * regexp.Regexp {
9899 return constants .JellyfinRegexp .Cache .Subtitle
99100}
100101
@@ -234,12 +235,26 @@ func (jellyfinHandler *JellyfinHandler) VideosHandler(ctx *gin.Context) {
234235
235236 // 并发控制:确保同一个 item ID 只有一个任务在运行
236237 // 将整个处理流程放在锁内,避免重复查询和重复获取重定向 URL
237- var mu * sync. Mutex
238+ var muWrapper * mutexWithRefCount
238239 if itemID != "" {
239- mutex , _ := jellyfinHandler .playbackInfoMutex .LoadOrStore (itemID , & sync.Mutex {})
240- mu = mutex .(* sync.Mutex )
241- mu .Lock ()
242- defer mu .Unlock ()
240+ // 加载或创建 mutex wrapper
241+ value , _ := jellyfinHandler .playbackInfoMutex .LoadOrStore (itemID , & mutexWithRefCount {})
242+ muWrapper = value .(* mutexWithRefCount )
243+
244+ // 增加引用计数
245+ atomic .AddInt32 (& muWrapper .refCount , 1 )
246+
247+ // 锁定并处理
248+ muWrapper .mu .Lock ()
249+ defer func () {
250+ muWrapper .mu .Unlock ()
251+ // 减少引用计数
252+ refCount := atomic .AddInt32 (& muWrapper .refCount , - 1 )
253+ // 如果没有其他 goroutine 在使用,删除这个 mutex 以避免内存泄漏
254+ if refCount == 0 {
255+ jellyfinHandler .playbackInfoMutex .Delete (itemID )
256+ }
257+ }()
243258 logging .Debugf ("开始处理 item %s 的 VideosHandler 请求" , itemID )
244259 }
245260
0 commit comments