cloudflare/pint
Publicmirrored from https://github.com/cloudflare/pintAvailable
internal/promapi/keylock.go
32lines · modecode
| 1 | package promapi |
| 2 | |
| 3 | import "sync" |
| 4 | |
| 5 | // https://medium.com/@petrlozhkin/kmutex-lock-mutex-by-unique-id-408467659c24 |
| 6 | type partitionLocker struct { |
| 7 | c *sync.Cond |
| 8 | l sync.Locker |
| 9 | s map[string]struct{} |
| 10 | } |
| 11 | |
| 12 | func newPartitionLocker(l sync.Locker) *partitionLocker { |
| 13 | return &partitionLocker{c: sync.NewCond(l), l: l, s: make(map[string]struct{})} |
| 14 | } |
| 15 | |
| 16 | func (p *partitionLocker) locked(id string) (ok bool) { _, ok = p.s[id]; return } |
| 17 | |
| 18 | func (p *partitionLocker) lock(id string) { |
| 19 | p.l.Lock() |
| 20 | defer p.l.Unlock() |
| 21 | for p.locked(id) { |
| 22 | p.c.Wait() |
| 23 | } |
| 24 | p.s[id] = struct{}{} |
| 25 | } |
| 26 | |
| 27 | func (p *partitionLocker) unlock(id string) { |
| 28 | p.l.Lock() |
| 29 | defer p.l.Unlock() |
| 30 | delete(p.s, id) |
| 31 | p.c.Broadcast() |
| 32 | } |
| 33 | |