File: atom.go

package info (click to toggle)
golang-github-linuxdeepin-go-x11-client 0.6.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 1,656 kB
  • sloc: python: 944; sh: 38; makefile: 17
file content (110 lines) | stat: -rw-r--r-- 2,087 bytes parent folder | download | duplicates (2)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package x

import (
	"sync"
)

type AtomCache struct {
	atoms     map[string]Atom
	atomNames map[Atom]string
	mu        sync.RWMutex
}

func (ac *AtomCache) getVal(name string) (val Atom, ok bool) {
	ac.mu.RLock()
	val, ok = ac.atoms[name]
	ac.mu.RUnlock()
	return
}

func (ac *AtomCache) getName(val Atom) (name string, ok bool) {
	ac.mu.RLock()
	name, ok = ac.atomNames[val]
	ac.mu.RUnlock()
	return
}

func (ac *AtomCache) store(name string, val Atom) {
	ac.mu.Lock()
	ac.atoms[name] = val
	ac.atomNames[val] = name
	ac.mu.Unlock()
}

func NewAtomCache() *AtomCache {
	ac := &AtomCache{
		atoms:     make(map[string]Atom),
		atomNames: make(map[Atom]string),
	}
	return ac
}

var defaultAtomCache *AtomCache
var defaultAtomCacheMu sync.Mutex

func (c *Conn) getAtomCache() *AtomCache {
	c.atomCacheMu.Lock()
	if c.atomCache == nil {
		// try default atom cache
		defaultAtomCacheMu.Lock()
		if defaultAtomCache == nil {
			defaultAtomCache = NewAtomCache()
		}
		c.atomCache = defaultAtomCache
		defaultAtomCacheMu.Unlock()
	}
	v := c.atomCache
	c.atomCacheMu.Unlock()
	return v
}

func (c *Conn) SetAtomCache(ac *AtomCache) {
	c.atomCacheMu.Lock()
	c.atomCache = ac
	c.atomCacheMu.Unlock()
}

func (c *Conn) GetAtomCache() (ac *AtomCache) {
	c.atomCacheMu.Lock()
	ac = c.atomCache
	c.atomCacheMu.Unlock()
	return
}

func (c *Conn) GetAtom(name string) (Atom, error) {
	return c.getAtom(false, name)
}

func (c *Conn) GetAtomExisting(name string) (Atom, error) {
	return c.getAtom(true, name)
}

func (c *Conn) getAtom(onlyIfExists bool, name string) (Atom, error) {
	ac := c.getAtomCache()
	val, ok := ac.getVal(name)
	if ok {
		return val, nil
	}

	reply, err := InternAtom(c, onlyIfExists, name).Reply(c)
	if err != nil {
		return AtomNone, err
	}
	ac.store(name, reply.Atom)
	return reply.Atom, nil
}

func (c *Conn) GetAtomName(atom Atom) (string, error) {
	ac := c.getAtomCache()
	name, ok := ac.getName(atom)
	if ok {
		return name, nil
	}

	reply, err := GetAtomName(c, atom).Reply(c)
	if err != nil {
		return "", err
	}
	ac.store(reply.Name, atom)
	return reply.Name, nil
}