1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
package proxy
import (
"errors"
"sync"
"github.com/godbus/dbus"
)
var globalRuleCounter = &ruleCounter{
connRuleCount: make(map[string]map[string]uint),
}
type ruleCounter struct {
connRuleCount map[string]map[string]uint
// ^unique name ^rule
mu sync.Mutex
}
func getConnName(conn *dbus.Conn) string {
return conn.Names()[0]
}
func (rc *ruleCounter) addMatch(conn *dbus.Conn, rule string) error {
name := getConnName(conn)
if name == "" {
return errors.New("conn name is empty")
}
rc.mu.Lock()
defer rc.mu.Unlock()
var count uint
ruleCount, ok := rc.connRuleCount[name]
if ok {
count = ruleCount[rule]
} else {
ruleCount = make(map[string]uint)
rc.connRuleCount[name] = ruleCount
}
if count == 0 {
err := conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule).Err
if err != nil {
return err
}
}
ruleCount[rule] = count + 1
return nil
}
func (rc *ruleCounter) removeMatch(conn *dbus.Conn, rule string) error {
name := getConnName(conn)
if name == "" {
return errors.New("conn name is empty")
}
rc.mu.Lock()
defer rc.mu.Unlock()
var count uint
ruleCount, ok := rc.connRuleCount[name]
if !ok {
return nil
}
count = ruleCount[rule]
if count == 1 {
err := conn.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, rule).Err
if err != nil {
return err
}
}
ruleCount[rule] = count - 1
return nil
}
func (rc *ruleCounter) deleteConn(conn *dbus.Conn) {
rc.mu.Lock()
delete(rc.connRuleCount, getConnName(conn))
rc.mu.Unlock()
}
// DeleteConn 删除连接相关的数据,可以在你关闭这个连接之后调用。
func DeleteConn(conn *dbus.Conn) {
globalRuleCounter.deleteConn(conn)
}
|