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

(cherry picked from commit ea03fb2788)
This commit is contained in:
bbedward
2026-07-24 10:42:27 -04:00
parent f455456ff1
commit 39278860c8
2 changed files with 69 additions and 35 deletions
+3 -2
View File
@@ -117,11 +117,12 @@ func RouteRequest(conn net.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
@@ -12,7 +12,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
@@ -85,8 +84,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
func getSocketDir() string { func getSocketDir() string {
if runtime := os.Getenv("XDG_RUNTIME_DIR"); runtime != "" { if runtime := os.Getenv("XDG_RUNTIME_DIR"); runtime != "" {
@@ -243,17 +242,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 {
@@ -463,7 +500,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")
} }
@@ -533,7 +570,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")
} }
@@ -997,38 +1034,31 @@ func handleSubscribe(conn net.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:
@@ -1338,9 +1368,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()
} }