/
locktab.go
65 lines (55 loc) · 1.32 KB
/
locktab.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package libkb
import (
"sync"
"golang.org/x/net/context"
)
type NamedLock struct {
sync.Mutex
lctx VLogContext
refs int
name string
parent *LockTable
}
func (l *NamedLock) incref() {
l.refs++
}
func (l *NamedLock) decref() {
l.refs--
}
func (l *NamedLock) Release(ctx context.Context) {
l.lctx.GetVDebugLog().CLogf(ctx, VLog1, "+ LockTable.Release(%s)", l.name)
l.Unlock()
l.parent.Lock()
l.decref()
if l.refs == 0 {
l.lctx.GetVDebugLog().CLogf(ctx, VLog1, "| LockTable.unref(%s)", l.name)
delete(l.parent.locks, l.name)
}
l.parent.Unlock()
l.lctx.GetVDebugLog().CLogf(ctx, VLog0, "- LockTable.Unlock(%s)", l.name)
}
type LockTable struct {
sync.Mutex
locks map[string]*NamedLock
}
func (t *LockTable) init() {
if t.locks == nil {
t.locks = make(map[string]*NamedLock)
}
}
func (t *LockTable) AcquireOnName(ctx context.Context, g VLogContext, s string) (ret *NamedLock) {
g.GetVDebugLog().CLogf(ctx, VLog0, "+ LockTable.Lock(%s)", s)
t.Lock()
t.init()
if ret = t.locks[s]; ret == nil {
ret = &NamedLock{lctx: g, refs: 0, name: s, parent: t}
t.locks[s] = ret
}
ret.incref()
t.Unlock()
ret.Lock()
g.GetVDebugLog().CLogf(ctx, VLog1, "- LockTable.Lock(%s)", s)
return ret
}