1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-01 19:18:28 -04:00

cups: fix initialization race

port 1.5
This commit is contained in:
bbedward
2026-07-24 10:42:27 -04:00
parent 0815e48465
commit ea03fb2788
2 changed files with 69 additions and 35 deletions
+3 -2
View File
@@ -116,11 +116,12 @@ func RouteRequest(conn *models.Conn, req models.Request) {
} }
if strings.HasPrefix(req.Method, "cups.") { if strings.HasPrefix(req.Method, "cups.") {
if cupsManager == nil { mgr, err := ensureCupsManager()
if err != nil {
models.RespondError(conn, req.ID, "CUPS manager not initialized") models.RespondError(conn, req.ID, "CUPS manager not initialized")
return return
} }
cups.HandleRequest(conn, req, cupsManager) cups.HandleRequest(conn, req, mgr)
return return
} }
+66 -33
View File
@@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"runtime/debug" "runtime/debug"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/AvengeMedia/DankMaterialShell/core/internal/geolocation" "github.com/AvengeMedia/DankMaterialShell/core/internal/geolocation"
@@ -80,8 +79,8 @@ var geoClientInstance geolocation.Client
const dbusClientID = "dms-dbus-client" const dbusClientID = "dms-dbus-client"
var capabilitySubscribers syncmap.Map[string, chan ServerInfo] var capabilitySubscribers syncmap.Map[string, chan ServerInfo]
var cupsSubscribers syncmap.Map[string, bool] var cupsMu sync.Mutex
var cupsSubscriberCount atomic.Int32 var cupsSubscriberCount int
var appPaths = paths.New("danklinux") var appPaths = paths.New("danklinux")
@@ -174,17 +173,55 @@ func InitializeAppPickerManager() error {
return nil return nil
} }
func InitializeCupsManager() error { func initializeCupsManagerLocked() (bool, error) {
if cupsManager != nil {
return false, nil
}
manager, err := cups.NewManager() manager, err := cups.NewManager()
if err != nil { if err != nil {
log.Warnf("Failed to initialize cups manager: %v", err) log.Warnf("Failed to initialize cups manager: %v", err)
return err return false, err
} }
cupsManager = manager cupsManager = manager
log.Info("CUPS manager initialized") log.Info("CUPS manager initialized")
return nil return true, nil
}
func ensureCupsManager() (*cups.Manager, error) {
cupsMu.Lock()
created, err := initializeCupsManagerLocked()
mgr := cupsManager
cupsMu.Unlock()
if err != nil {
return nil, err
}
if created {
notifyCapabilityChange()
}
return mgr, nil
}
func cupsAvailable() bool {
cupsMu.Lock()
defer cupsMu.Unlock()
return cupsManager != nil
}
func releaseCupsSubscriber() {
cupsMu.Lock()
cupsSubscriberCount--
var mgr *cups.Manager
if cupsSubscriberCount == 0 && cupsManager != nil {
mgr = cupsManager
cupsManager = nil
}
cupsMu.Unlock()
if mgr == nil {
return
}
log.Info("Last CUPS subscriber disconnected, shutting down CUPS manager")
mgr.Close()
notifyCapabilityChange()
} }
func InitializeBrightnessManager() error { func InitializeBrightnessManager() error {
@@ -379,7 +416,7 @@ func getCapabilities() Capabilities {
caps = append(caps, "browser") caps = append(caps, "browser")
} }
if cupsManager != nil { if cupsAvailable() {
caps = append(caps, "cups") caps = append(caps, "cups")
} }
@@ -449,7 +486,7 @@ func getServerInfo() ServerInfo {
caps = append(caps, "browser") caps = append(caps, "browser")
} }
if cupsManager != nil { if cupsAvailable() {
caps = append(caps, "cups") caps = append(caps, "cups")
} }
@@ -913,38 +950,31 @@ func handleSubscribe(conn *models.Conn, req models.Request) {
} }
if shouldSubscribe("cups") { if shouldSubscribe("cups") {
cupsSubscribers.Store(clientID+"-cups", true) cupsMu.Lock()
count := cupsSubscriberCount.Add(1) cupsSubscriberCount++
created, err := initializeCupsManagerLocked()
mgr := cupsManager
cupsMu.Unlock()
if count == 1 { if err != nil {
if err := InitializeCupsManager(); err != nil { log.Warnf("Failed to initialize CUPS manager for subscription: %v", err)
log.Warnf("Failed to initialize CUPS manager for subscription: %v", err) } else if created {
} else { notifyCapabilityChange()
notifyCapabilityChange()
}
} }
if cupsManager != nil { if mgr == nil {
releaseCupsSubscriber()
} else {
wg.Add(1) wg.Add(1)
cupsChan := cupsManager.Subscribe(clientID + "-cups") cupsChan := mgr.Subscribe(clientID + "-cups")
go func() { go func() {
defer wg.Done() defer wg.Done()
defer func() { defer func() {
cupsManager.Unsubscribe(clientID + "-cups") mgr.Unsubscribe(clientID + "-cups")
cupsSubscribers.Delete(clientID + "-cups") releaseCupsSubscriber()
count := cupsSubscriberCount.Add(-1)
if count == 0 {
log.Info("Last CUPS subscriber disconnected, shutting down CUPS manager")
if cupsManager != nil {
cupsManager.Close()
cupsManager = nil
notifyCapabilityChange()
}
}
}() }()
initialState := cupsManager.GetState() initialState := mgr.GetState()
select { select {
case eventChan <- ServiceEvent{Service: "cups", Data: initialState}: case eventChan <- ServiceEvent{Service: "cups", Data: initialState}:
case <-stopChan: case <-stopChan:
@@ -1254,9 +1284,12 @@ func cleanupManagers() {
if appPickerManager != nil { if appPickerManager != nil {
appPickerManager.Close() appPickerManager.Close()
} }
cupsMu.Lock()
if cupsManager != nil { if cupsManager != nil {
cupsManager.Close() cupsManager.Close()
cupsManager = nil
} }
cupsMu.Unlock()
if brightnessManager != nil { if brightnessManager != nil {
brightnessManager.Close() brightnessManager.Close()
} }