func LockFile(fileName string) error { f, err := os.Create(fileName) if err != nil { return err } return unix.Flock(int(f.Fd()), unix.LOCK_EX|unix.LOCK_NB) }
// HaveLock checks if we have an exclusive flock lock on the file. // flocks(2) can be inherited by child processes. func HaveLock(f *os.File) bool { var how int = unix.LOCK_EX | unix.LOCK_NB err := unix.Flock(int(f.Fd()), how) if err == nil { return true } return false }
// LockFile returns nil if the lock was obtained. // If the lock was not obtained, NoLockErr is // returned func LockFile(f *os.File) error { var how int = unix.LOCK_EX | unix.LOCK_NB err := unix.Flock(int(f.Fd()), how) if err == unix.EWOULDBLOCK { return NoLockErr } else { return nil } }
func UnlockFile(f *os.File) error { defer f.Close() if err := unix.Flock(int(f.Fd()), unix.LOCK_UN); err != nil { return err } if _, err := Execute("rm", []string{f.Name()}); err != nil { return err } return nil }
func LockFile(fileName string) (*os.File, error) { f, err := os.Create(fileName) if err != nil { return nil, err } if err := unix.Flock(int(f.Fd()), unix.LOCK_EX|unix.LOCK_NB); err != nil { f.Close() return nil, err } return f, nil }
func UnlockFile(fileName string) error { f, err := os.Open(fileName) if err != nil { return err } defer f.Close() if err := unix.Flock(int(f.Fd()), unix.LOCK_UN); err != nil { return err } if _, err := Execute("rm", []string{fileName}); err != nil { return err } return nil }
// UnLock free lock set by SharedLock() (or second lock set by ExclusiveLock()). // // Do nothing if $NARADA_SKIP_LOCK is not empty. func (l Lock) UnLock() error { if os.Getenv("NARADA_SKIP_LOCK") != "" { return nil } if l.f == nil { return nil } if err := unix.Flock(int(l.f.Fd()), unix.LOCK_UN); err != nil { return err } if err := l.f.Close(); err != nil { return err } l.f = nil return nil }
// SharedLock try to get shared lock which is required to modify any // project data (files or database). // // If wait <= 0 will wait forever until lock will be granted. // // Do nothing if $NARADA_SKIP_LOCK is not empty. func SharedLock(wait time.Duration) (l Lock, err error) { var waited time.Duration if os.Getenv("NARADA_SKIP_LOCK") != "" { return } if l.f, err = os.OpenFile(lockfile, os.O_RDONLY|os.O_CREATE, 0644); err != nil { return } for { _, err2 := os.Stat(locknew) if err2 != nil && os.IsNotExist(err2) { err = unix.Flock(int(l.f.Fd()), unix.LOCK_SH|unix.LOCK_NB) if err == nil || err != unix.EWOULDBLOCK { return } err = nil } if wait > 0 && waited >= wait { return l, ErrLockTimeout } time.Sleep(tick) waited += tick } }
// Unlock calls flock with LOCK_UN, and returns any error. // Typically the returned error is nil whether we succeeded // or not in unlocking the file. Note that the operating // system automatically unlocks flocks when the process // exits. func UnlockFile(f *os.File) error { var how int = unix.LOCK_UN return unix.Flock(int(f.Fd()), how) }