generated from moul/golang-repo-template
/
sync.go
46 lines (40 loc) 路 1.06 KB
/
sync.go
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
package u
import (
"sync"
)
// MutexMap manages a pool of mutexes that can be get by key.
// MutexMap is thread-safe.
type MutexMap struct {
self sync.Mutex
entries map[string]*sync.RWMutex
}
// Lock locks a mutex by key, and returns a callback for unlocking unlock.
// Lock will automatically create a new mutex for new keys.
func (mm *MutexMap) Lock(key string) func() {
mm.self.Lock()
if mm.entries == nil {
mm.entries = make(map[string]*sync.RWMutex)
}
if _, found := mm.entries[key]; !found {
mm.entries[key] = &sync.RWMutex{}
}
entry := mm.entries[key]
entry.Lock()
mm.self.Unlock()
return entry.Unlock
}
// RLock locks a mutex by key for reading, and returns a callback for unlocking unlock.
// RLock will automatically create a new mutex for new keys.
func (mm *MutexMap) RLock(key string) func() {
mm.self.Lock()
if mm.entries == nil {
mm.entries = make(map[string]*sync.RWMutex)
}
if _, found := mm.entries[key]; !found {
mm.entries[key] = &sync.RWMutex{}
}
entry := mm.entries[key]
entry.RLock()
mm.self.Unlock()
return entry.RUnlock
}