github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/flock/flock_unix.go (about)

     1  // +build !windows,!plan9
     2  
     3  package flock
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"syscall"
     9  )
    10  
    11  // FileLockGuard holds a lock of file on a directory.
    12  type FileLockGuard struct {
    13  	// file descriptor on directory.
    14  	fd *os.File
    15  }
    16  
    17  // AcquireFileLock acquire the lock on the directory by syscall.Flock.
    18  // Return a FileLockGuard or an error, if any.
    19  func AcquireFileLock(path string, readOnly bool) (*FileLockGuard, error) {
    20  	var flag = os.O_RDWR
    21  	if readOnly {
    22  		flag = os.O_RDONLY
    23  	}
    24  	file, err := os.OpenFile(path, flag, 0)
    25  	if os.IsNotExist(err) {
    26  		file, err = os.OpenFile(path, flag|os.O_CREATE, 0644)
    27  	}
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	var how = syscall.LOCK_EX | syscall.LOCK_NB
    33  	if readOnly {
    34  		how = syscall.LOCK_SH | syscall.LOCK_NB
    35  	}
    36  	if err := syscall.Flock(int(file.Fd()), how); err != nil {
    37  		return nil, err
    38  	}
    39  	return &FileLockGuard{fd: file}, nil
    40  }
    41  
    42  // SyncDir commits the current contents of the directory to stable storage.
    43  func SyncDir(path string) error {
    44  	fd, err := os.Open(path)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	err = fd.Sync()
    49  	closeErr := fd.Close()
    50  	if err != nil {
    51  		return fmt.Errorf("sync dir err: %+v", err)
    52  	}
    53  	if closeErr != nil {
    54  		return fmt.Errorf("close dir err: %+v", err)
    55  	}
    56  	return nil
    57  }
    58  
    59  // Release release the file lock.
    60  func (fl *FileLockGuard) Release() error {
    61  	how := syscall.LOCK_UN | syscall.LOCK_NB
    62  	if err := syscall.Flock(int(fl.fd.Fd()), how); err != nil {
    63  		return err
    64  	}
    65  	return fl.fd.Close()
    66  }