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  }