From 5353429b8c4b7504ab39d91b9da60fa91031bd68 Mon Sep 17 00:00:00 2001 From: starainrt Date: Wed, 1 Sep 2021 13:52:43 +0800 Subject: [PATCH] shared lock support --- files_test.go | 7 ++++--- files_unix.go | 24 ++++++++++++++++++------ files_windows.go | 30 ++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/files_test.go b/files_test.go index 5328fe4..7d7637c 100644 --- a/files_test.go +++ b/files_test.go @@ -11,12 +11,13 @@ func Test_FileLock(t *testing.T) { filename := "./test.file" lock := NewFileLock(filename) lock2 := NewFileLock(filename) - fmt.Println("lock1", lock.LockNoBlocking()) + fmt.Println("lock1", lock.LockNoBlocking(false)) time.Sleep(time.Second) - fmt.Println("lock2", lock2.LockWithTimeout(time.Second*5)) + fmt.Println("lock2", lock2.LockWithTimeout(time.Second*5, false)) fmt.Println("unlock1", lock.Unlock()) time.Sleep(time.Second) - fmt.Println("lock2", lock2.LockNoBlocking()) + fmt.Println("unlock2", lock2.Unlock()) + fmt.Println("lock2", lock2.LockNoBlocking(true)) fmt.Println("unlock2", lock2.Unlock()) os.Remove(filename) } diff --git a/files_unix.go b/files_unix.go index 8580863..5f57429 100644 --- a/files_unix.go +++ b/files_unix.go @@ -36,18 +36,30 @@ func (f *FileLock) openFileForLock() error { return nil } -func (f *FileLock) Lock() error { +func (f *FileLock) Lock(Exclusive bool) error { + var lockType int + if Exclusive { + lockType = syscall.LOCK_EX + } else { + lockType = syscall.LOCK_SH + } if err := f.openFileForLock(); err != nil { return err } - return syscall.Flock(f.fd, syscall.LOCK_EX) + return syscall.Flock(f.fd, lockType) } -func (f *FileLock) LockNoBlocking() error { +func (f *FileLock) LockNoBlocking(Exclusive bool) error { + var lockType int + if Exclusive { + lockType = syscall.LOCK_EX + } else { + lockType = syscall.LOCK_SH + } if err := f.openFileForLock(); err != nil { return err } - err := syscall.Flock(f.fd, syscall.LOCK_EX|syscall.LOCK_NB) + err := syscall.Flock(f.fd, lockType|syscall.LOCK_NB) if err != nil { syscall.Close(f.fd) if err == syscall.EWOULDBLOCK { @@ -65,9 +77,9 @@ func (f *FileLock) Unlock() error { return syscall.Close(f.fd) } -func (f *FileLock) LockWithTimeout(tm time.Duration) error { +func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error { return stario.StopUntilTimeout(tm, func(tmout chan struct{}) error { - err := f.Lock() + err := f.Lock(Exclusive) select { case <-tmout: f.Unlock() diff --git a/files_windows.go b/files_windows.go index 7c8aba5..6ca87d9 100644 --- a/files_windows.go +++ b/files_windows.go @@ -88,16 +88,34 @@ func (f *FileLock) lockForTimeout(timeout time.Duration, lockType win32api.DWORD } } -func (f *FileLock) Lock() error { - return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK) +func (f *FileLock) Lock(Exclusive bool) error { + var lockType win32api.DWORD + if Exclusive { + lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK + } else { + lockType = 0 + } + return f.lockForTimeout(0, lockType) } -func (f *FileLock) LockWithTimeout(tm time.Duration) error { - return f.lockForTimeout(tm, win32api.LOCKFILE_EXCLUSIVE_LOCK) +func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error { + var lockType win32api.DWORD + if Exclusive { + lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK + } else { + lockType = 0 + } + return f.lockForTimeout(tm, lockType) } -func (f *FileLock) LockNoBlocking() error { - return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK|win32api.LOCKFILE_FAIL_IMMEDIATELY) +func (f *FileLock) LockNoBlocking(Exclusive bool) error { + var lockType win32api.DWORD + if Exclusive { + lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK + } else { + lockType = 0 + } + return f.lockForTimeout(0, lockType|win32api.LOCKFILE_FAIL_IMMEDIATELY) } func (f *FileLock) Unlock() error {