/
sigchain_guard.go
51 lines (44 loc) · 1.44 KB
/
sigchain_guard.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
package libkb
import (
"sync"
"golang.org/x/net/context"
)
// A guard used to tell background tasks to stay off the sigchain
// while the user is changing their sigchain on purpose.
// Don't treat this as a lock, it's very sloppy.
// The guard exists to avoid races where an intentional action like provisioning
// loads the sigchain, but then it gets changed by a background task,
// so the intentional action would fail.
// This is just an atomic bool. Intentional actions can acquire it
// multiple times, release it even when others have it,
// so it's sloppy, but you'll never deadlock.
type LocalSigchainGuard struct {
Contextified
mu sync.Mutex
acquired bool
}
func NewLocalSigchainGuard(g *GlobalContext) *LocalSigchainGuard {
return &LocalSigchainGuard{
Contextified: NewContextified(g),
acquired: false,
}
}
func (l *LocalSigchainGuard) Set(ctx context.Context, reason string) {
l.G().Log.CDebugf(ctx, "LocalSigchainGuard#Set(%v)", reason)
l.mu.Lock()
defer l.mu.Unlock()
l.acquired = true
}
func (l *LocalSigchainGuard) Clear(ctx context.Context, reason string) {
l.G().Log.CDebugf(ctx, "LocalSigchainGuard#Clear(%v)", reason)
l.mu.Lock()
defer l.mu.Unlock()
l.acquired = false
}
func (l *LocalSigchainGuard) IsAvailable(ctx context.Context, reason string) bool {
l.mu.Lock()
acquired := l.acquired
l.mu.Unlock()
l.G().Log.CDebugf(ctx, "LocalSigchainGuard#IsAvailable(%v) -> %v", reason, !acquired)
return !acquired
}