fix(01-01): add mutex protection to Queue, Library, and Playlist SetContext methods
- Queue.SetContext acquires existing q.mu before writing q.ctx - Library struct gets new mu sync.Mutex; SetContext and SetRescanHooks acquire it - Playlist Service struct gets new mu sync.Mutex; SetContext and SetFavoritesConfig acquire it - Library and Playlist release lock before calling post-init methods (registerEventHandlers, migrateExistingPlaylists)
This commit is contained in:
@@ -76,6 +76,9 @@ type RescanHooks struct {
|
|||||||
|
|
||||||
// Library manages scanning and querying the music collection.
|
// Library manages scanning and querying the music collection.
|
||||||
type Library struct {
|
type Library struct {
|
||||||
|
// mu protects ctx, conf, and rescanHooks from concurrent
|
||||||
|
// access during initialization.
|
||||||
|
mu sync.Mutex
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
conf *Config
|
conf *Config
|
||||||
@@ -86,6 +89,9 @@ type Library struct {
|
|||||||
// SetRescanHooks provides optional hooks for cross-cutting
|
// SetRescanHooks provides optional hooks for cross-cutting
|
||||||
// orchestration during FullRescan.
|
// orchestration during FullRescan.
|
||||||
func (l *Library) SetRescanHooks(h RescanHooks) {
|
func (l *Library) SetRescanHooks(h RescanHooks) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
|
|
||||||
l.rescanHooks = h
|
l.rescanHooks = h
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +124,10 @@ func NewLibrary(
|
|||||||
|
|
||||||
// SetContext sets the Wails runtime context and registers event handlers.
|
// SetContext sets the Wails runtime context and registers event handlers.
|
||||||
func (l *Library) SetContext(ctx context.Context) {
|
func (l *Library) SetContext(ctx context.Context) {
|
||||||
|
l.mu.Lock()
|
||||||
l.ctx = ctx
|
l.ctx = ctx
|
||||||
|
l.mu.Unlock()
|
||||||
|
|
||||||
l.registerEventHandlers()
|
l.registerEventHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||||
|
|
||||||
@@ -96,6 +97,9 @@ type PhantomSearchResult struct {
|
|||||||
|
|
||||||
// Service manages playlist operations.
|
// Service manages playlist operations.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
// mu protects ctx and favoritesConf from concurrent access
|
||||||
|
// during initialization.
|
||||||
|
mu sync.Mutex
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
db *database.DB
|
db *database.DB
|
||||||
@@ -121,6 +125,9 @@ func NewService(
|
|||||||
func (s *Service) SetFavoritesConfig(
|
func (s *Service) SetFavoritesConfig(
|
||||||
provider FavoritesConfigProvider,
|
provider FavoritesConfigProvider,
|
||||||
) {
|
) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
s.favoritesConf = provider
|
s.favoritesConf = provider
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +135,10 @@ func (s *Service) SetFavoritesConfig(
|
|||||||
// one-time startup migration to bootstrap M3U8 files for
|
// one-time startup migration to bootstrap M3U8 files for
|
||||||
// existing playlists.
|
// existing playlists.
|
||||||
func (s *Service) SetContext(ctx context.Context) {
|
func (s *Service) SetContext(ctx context.Context) {
|
||||||
|
s.mu.Lock()
|
||||||
s.ctx = ctx
|
s.ctx = ctx
|
||||||
|
s.mu.Unlock()
|
||||||
|
|
||||||
s.migrateExistingPlaylists()
|
s.migrateExistingPlaylists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ func NewQueue(logger *slog.Logger, db *database.DB) *Queue {
|
|||||||
|
|
||||||
// SetContext sets the Wails runtime context for event emission.
|
// SetContext sets the Wails runtime context for event emission.
|
||||||
func (q *Queue) SetContext(ctx context.Context) {
|
func (q *Queue) SetContext(ctx context.Context) {
|
||||||
|
q.mu.Lock()
|
||||||
|
defer q.mu.Unlock()
|
||||||
|
|
||||||
q.ctx = ctx
|
q.ctx = ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user