github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/daemon/lock.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 6 "github.com/mutagen-io/mutagen/pkg/filesystem/locking" 7 ) 8 9 // Lock represents the global daemon lock. It is held by a single daemon 10 // instance at a time. 11 type Lock struct { 12 // locker is the underlying file locker. 13 locker *locking.Locker 14 } 15 16 // AcquireLock attempts to acquire the global daemon lock. 17 func AcquireLock() (*Lock, error) { 18 // Compute the lock path. 19 lockPath, err := subpath(lockName) 20 if err != nil { 21 return nil, fmt.Errorf("unable to compute daemon lock path: %w", err) 22 } 23 24 // Create the locker and attempt to acquire the lock. 25 locker, err := locking.NewLocker(lockPath, 0600) 26 if err != nil { 27 return nil, fmt.Errorf("unable to create daemon file locker: %w", err) 28 } else if err = locker.Lock(false); err != nil { 29 locker.Close() 30 return nil, err 31 } 32 33 // Create the lock. 34 return &Lock{ 35 locker: locker, 36 }, nil 37 } 38 39 // Release releases the daemon lock. 40 func (l *Lock) Release() error { 41 // Release the lock. 42 if err := l.locker.Unlock(); err != nil { 43 l.locker.Close() 44 return err 45 } 46 47 // Close the locker. 48 if err := l.locker.Close(); err != nil { 49 return fmt.Errorf("unable to close locker: %w", err) 50 } 51 52 // Success. 53 return nil 54 }