mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-11 07:52:50 -05:00
core: refactor to use a generic-compatible syncmap
This commit is contained in:
@@ -32,14 +32,11 @@ func NewManager() (*Manager, error) {
|
||||
},
|
||||
stateMutex: sync.RWMutex{},
|
||||
|
||||
stopChan: make(chan struct{}),
|
||||
dbusConn: conn,
|
||||
signals: make(chan *dbus.Signal, 256),
|
||||
pairingSubscribers: make(map[string]chan PairingPrompt),
|
||||
pairingSubMutex: sync.RWMutex{},
|
||||
dirty: make(chan struct{}, 1),
|
||||
pendingPairings: make(map[string]bool),
|
||||
eventQueue: make(chan func(), 32),
|
||||
stopChan: make(chan struct{}),
|
||||
dbusConn: conn,
|
||||
signals: make(chan *dbus.Signal, 256),
|
||||
dirty: make(chan struct{}, 1),
|
||||
eventQueue: make(chan func(), 32),
|
||||
}
|
||||
|
||||
broker := NewSubscriptionBroker(m.broadcastPairingPrompt)
|
||||
@@ -359,12 +356,7 @@ func (m *Manager) handleDevicePropertiesChanged(path dbus.ObjectPath, changed ma
|
||||
if hasPaired {
|
||||
if paired, ok := pairedVar.Value().(bool); ok && paired {
|
||||
devicePath := string(path)
|
||||
m.pendingPairingsMux.Lock()
|
||||
wasPending := m.pendingPairings[devicePath]
|
||||
if wasPending {
|
||||
delete(m.pendingPairings, devicePath)
|
||||
}
|
||||
m.pendingPairingsMux.Unlock()
|
||||
_, wasPending := m.pendingPairings.LoadAndDelete(devicePath)
|
||||
|
||||
if wasPending {
|
||||
select {
|
||||
@@ -436,8 +428,7 @@ func (m *Manager) notifier() {
|
||||
continue
|
||||
}
|
||||
|
||||
m.subscribers.Range(func(key, value interface{}) bool {
|
||||
ch := value.(chan BluetoothState)
|
||||
m.subscribers.Range(func(key string, ch chan BluetoothState) bool {
|
||||
select {
|
||||
case ch <- currentState:
|
||||
default:
|
||||
@@ -481,38 +472,31 @@ func (m *Manager) Subscribe(id string) chan BluetoothState {
|
||||
}
|
||||
|
||||
func (m *Manager) Unsubscribe(id string) {
|
||||
if val, ok := m.subscribers.LoadAndDelete(id); ok {
|
||||
close(val.(chan BluetoothState))
|
||||
if ch, ok := m.subscribers.LoadAndDelete(id); ok {
|
||||
close(ch)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) SubscribePairing(id string) chan PairingPrompt {
|
||||
ch := make(chan PairingPrompt, 16)
|
||||
m.pairingSubMutex.Lock()
|
||||
m.pairingSubscribers[id] = ch
|
||||
m.pairingSubMutex.Unlock()
|
||||
m.pairingSubscribers.Store(id, ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
func (m *Manager) UnsubscribePairing(id string) {
|
||||
m.pairingSubMutex.Lock()
|
||||
if ch, ok := m.pairingSubscribers[id]; ok {
|
||||
if ch, ok := m.pairingSubscribers.LoadAndDelete(id); ok {
|
||||
close(ch)
|
||||
delete(m.pairingSubscribers, id)
|
||||
}
|
||||
m.pairingSubMutex.Unlock()
|
||||
}
|
||||
|
||||
func (m *Manager) broadcastPairingPrompt(prompt PairingPrompt) {
|
||||
m.pairingSubMutex.RLock()
|
||||
defer m.pairingSubMutex.RUnlock()
|
||||
|
||||
for _, ch := range m.pairingSubscribers {
|
||||
m.pairingSubscribers.Range(func(key string, ch chan PairingPrompt) bool {
|
||||
select {
|
||||
case ch <- prompt:
|
||||
default:
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) SubmitPairing(token string, secrets map[string]string, accept bool) error {
|
||||
@@ -553,17 +537,13 @@ func (m *Manager) SetPowered(powered bool) error {
|
||||
}
|
||||
|
||||
func (m *Manager) PairDevice(devicePath string) error {
|
||||
m.pendingPairingsMux.Lock()
|
||||
m.pendingPairings[devicePath] = true
|
||||
m.pendingPairingsMux.Unlock()
|
||||
m.pendingPairings.Store(devicePath, true)
|
||||
|
||||
obj := m.dbusConn.Object(bluezService, dbus.ObjectPath(devicePath))
|
||||
err := obj.Call(device1Iface+".Pair", 0).Err
|
||||
|
||||
if err != nil {
|
||||
m.pendingPairingsMux.Lock()
|
||||
delete(m.pendingPairings, devicePath)
|
||||
m.pendingPairingsMux.Unlock()
|
||||
m.pendingPairings.Delete(devicePath)
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -605,19 +585,17 @@ func (m *Manager) Close() {
|
||||
m.agent.Close()
|
||||
}
|
||||
|
||||
m.subscribers.Range(func(key, value interface{}) bool {
|
||||
ch := value.(chan BluetoothState)
|
||||
m.subscribers.Range(func(key string, ch chan BluetoothState) bool {
|
||||
close(ch)
|
||||
m.subscribers.Delete(key)
|
||||
return true
|
||||
})
|
||||
|
||||
m.pairingSubMutex.Lock()
|
||||
for _, ch := range m.pairingSubscribers {
|
||||
m.pairingSubscribers.Range(func(key string, ch chan PairingPrompt) bool {
|
||||
close(ch)
|
||||
}
|
||||
m.pairingSubscribers = make(map[string]chan PairingPrompt)
|
||||
m.pairingSubMutex.Unlock()
|
||||
m.pairingSubscribers.Delete(key)
|
||||
return true
|
||||
})
|
||||
|
||||
if m.dbusConn != nil {
|
||||
m.dbusConn.Close()
|
||||
|
||||
@@ -3,22 +3,19 @@ package bluez
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/errdefs"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
||||
)
|
||||
|
||||
type SubscriptionBroker struct {
|
||||
mu sync.RWMutex
|
||||
pending map[string]chan PromptReply
|
||||
requests map[string]PromptRequest
|
||||
pending syncmap.Map[string, chan PromptReply]
|
||||
requests syncmap.Map[string, PromptRequest]
|
||||
broadcastPrompt func(PairingPrompt)
|
||||
}
|
||||
|
||||
func NewSubscriptionBroker(broadcastPrompt func(PairingPrompt)) PromptBroker {
|
||||
return &SubscriptionBroker{
|
||||
pending: make(map[string]chan PromptReply),
|
||||
requests: make(map[string]PromptRequest),
|
||||
broadcastPrompt: broadcastPrompt,
|
||||
}
|
||||
}
|
||||
@@ -30,10 +27,8 @@ func (b *SubscriptionBroker) Ask(ctx context.Context, req PromptRequest) (string
|
||||
}
|
||||
|
||||
replyChan := make(chan PromptReply, 1)
|
||||
b.mu.Lock()
|
||||
b.pending[token] = replyChan
|
||||
b.requests[token] = req
|
||||
b.mu.Unlock()
|
||||
b.pending.Store(token, replyChan)
|
||||
b.requests.Store(token, req)
|
||||
|
||||
if b.broadcastPrompt != nil {
|
||||
prompt := PairingPrompt{
|
||||
@@ -53,10 +48,7 @@ func (b *SubscriptionBroker) Ask(ctx context.Context, req PromptRequest) (string
|
||||
}
|
||||
|
||||
func (b *SubscriptionBroker) Wait(ctx context.Context, token string) (PromptReply, error) {
|
||||
b.mu.RLock()
|
||||
replyChan, exists := b.pending[token]
|
||||
b.mu.RUnlock()
|
||||
|
||||
replyChan, exists := b.pending.Load(token)
|
||||
if !exists {
|
||||
return PromptReply{}, fmt.Errorf("unknown token: %s", token)
|
||||
}
|
||||
@@ -75,10 +67,7 @@ func (b *SubscriptionBroker) Wait(ctx context.Context, token string) (PromptRepl
|
||||
}
|
||||
|
||||
func (b *SubscriptionBroker) Resolve(token string, reply PromptReply) error {
|
||||
b.mu.RLock()
|
||||
replyChan, exists := b.pending[token]
|
||||
b.mu.RUnlock()
|
||||
|
||||
replyChan, exists := b.pending.Load(token)
|
||||
if !exists {
|
||||
return fmt.Errorf("unknown or expired token: %s", token)
|
||||
}
|
||||
@@ -92,8 +81,6 @@ func (b *SubscriptionBroker) Resolve(token string, reply PromptReply) error {
|
||||
}
|
||||
|
||||
func (b *SubscriptionBroker) cleanup(token string) {
|
||||
b.mu.Lock()
|
||||
delete(b.pending, token)
|
||||
delete(b.requests, token)
|
||||
b.mu.Unlock()
|
||||
b.pending.Delete(token)
|
||||
b.requests.Delete(token)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package bluez
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
@@ -59,21 +60,19 @@ type PairingPrompt struct {
|
||||
type Manager struct {
|
||||
state *BluetoothState
|
||||
stateMutex sync.RWMutex
|
||||
subscribers sync.Map
|
||||
subscribers syncmap.Map[string, chan BluetoothState]
|
||||
stopChan chan struct{}
|
||||
dbusConn *dbus.Conn
|
||||
signals chan *dbus.Signal
|
||||
sigWG sync.WaitGroup
|
||||
agent *BluezAgent
|
||||
promptBroker PromptBroker
|
||||
pairingSubscribers map[string]chan PairingPrompt
|
||||
pairingSubMutex sync.RWMutex
|
||||
pairingSubscribers syncmap.Map[string, chan PairingPrompt]
|
||||
dirty chan struct{}
|
||||
notifierWg sync.WaitGroup
|
||||
lastNotifiedState *BluetoothState
|
||||
adapterPath dbus.ObjectPath
|
||||
pendingPairings map[string]bool
|
||||
pendingPairingsMux sync.Mutex
|
||||
pendingPairings syncmap.Map[string, bool]
|
||||
eventQueue chan func()
|
||||
eventWg sync.WaitGroup
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user