shared lock support

master
兔子 3 years ago
parent cf453821ef
commit 5353429b8c

@ -11,12 +11,13 @@ func Test_FileLock(t *testing.T) {
filename := "./test.file" filename := "./test.file"
lock := NewFileLock(filename) lock := NewFileLock(filename)
lock2 := NewFileLock(filename) lock2 := NewFileLock(filename)
fmt.Println("lock1", lock.LockNoBlocking()) fmt.Println("lock1", lock.LockNoBlocking(false))
time.Sleep(time.Second) 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()) fmt.Println("unlock1", lock.Unlock())
time.Sleep(time.Second) 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()) fmt.Println("unlock2", lock2.Unlock())
os.Remove(filename) os.Remove(filename)
} }

@ -36,18 +36,30 @@ func (f *FileLock) openFileForLock() error {
return nil 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 { if err := f.openFileForLock(); err != nil {
return err 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 { if err := f.openFileForLock(); err != nil {
return err 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 { if err != nil {
syscall.Close(f.fd) syscall.Close(f.fd)
if err == syscall.EWOULDBLOCK { if err == syscall.EWOULDBLOCK {
@ -65,9 +77,9 @@ func (f *FileLock) Unlock() error {
return syscall.Close(f.fd) 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 { return stario.StopUntilTimeout(tm, func(tmout chan struct{}) error {
err := f.Lock() err := f.Lock(Exclusive)
select { select {
case <-tmout: case <-tmout:
f.Unlock() f.Unlock()

@ -88,16 +88,34 @@ func (f *FileLock) lockForTimeout(timeout time.Duration, lockType win32api.DWORD
} }
} }
func (f *FileLock) Lock() error { func (f *FileLock) Lock(Exclusive bool) error {
return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK) 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 { func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
return f.lockForTimeout(tm, win32api.LOCKFILE_EXCLUSIVE_LOCK) var lockType win32api.DWORD
if Exclusive {
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
} else {
lockType = 0
}
return f.lockForTimeout(tm, lockType)
} }
func (f *FileLock) LockNoBlocking() error { func (f *FileLock) LockNoBlocking(Exclusive bool) error {
return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK|win32api.LOCKFILE_FAIL_IMMEDIATELY) 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 { func (f *FileLock) Unlock() error {

Loading…
Cancel
Save