github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/sigchain_guard.go (about) 1 package libkb 2 3 import ( 4 "sync" 5 6 "golang.org/x/net/context" 7 ) 8 9 // A guard used to tell background tasks to stay off the sigchain 10 // while the user is changing their sigchain on purpose. 11 // Don't treat this as a lock, it's very sloppy. 12 // The guard exists to avoid races where an intentional action like provisioning 13 // loads the sigchain, but then it gets changed by a background task, 14 // so the intentional action would fail. 15 // This is just an atomic bool. Intentional actions can acquire it 16 // multiple times, release it even when others have it, 17 // so it's sloppy, but you'll never deadlock. 18 type LocalSigchainGuard struct { 19 Contextified 20 mu sync.Mutex 21 acquired bool 22 } 23 24 func NewLocalSigchainGuard(g *GlobalContext) *LocalSigchainGuard { 25 return &LocalSigchainGuard{ 26 Contextified: NewContextified(g), 27 acquired: false, 28 } 29 } 30 31 func (l *LocalSigchainGuard) Set(ctx context.Context, reason string) { 32 l.G().Log.CDebugf(ctx, "LocalSigchainGuard#Set(%v)", reason) 33 l.mu.Lock() 34 defer l.mu.Unlock() 35 l.acquired = true 36 } 37 38 func (l *LocalSigchainGuard) Clear(ctx context.Context, reason string) { 39 l.G().Log.CDebugf(ctx, "LocalSigchainGuard#Clear(%v)", reason) 40 l.mu.Lock() 41 defer l.mu.Unlock() 42 l.acquired = false 43 } 44 45 func (l *LocalSigchainGuard) IsAvailable(ctx context.Context, reason string) bool { 46 l.mu.Lock() 47 acquired := l.acquired 48 l.mu.Unlock() 49 l.G().Log.CDebugf(ctx, "LocalSigchainGuard#IsAvailable(%v) -> %v", reason, !acquired) 50 return !acquired 51 }