mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
client/pkg/fileutil: use golang.org/x/sys/windows for FileLockEx
Use the FileLockEx wrapper and the corresponding LOCKFILE_* and error constants from the golang.org/x/sys/windows package rather than implementing these in the fileutil package.
This commit is contained in:
parent
dcf60888bc
commit
c3fe63a658
@ -22,31 +22,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var errLocked = errors.New("the process cannot access the file because another process has locked a portion of the file")
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
procLockFileEx = modkernel32.NewProc("LockFileEx")
|
|
||||||
|
|
||||||
errLocked = errors.New("the process cannot access the file because another process has locked a portion of the file")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
|
|
||||||
LOCKFILE_EXCLUSIVE_LOCK = 2
|
|
||||||
LOCKFILE_FAIL_IMMEDIATELY = 1
|
|
||||||
|
|
||||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
|
|
||||||
errLockViolation syscall.Errno = 0x21
|
|
||||||
)
|
|
||||||
|
|
||||||
func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
|
func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
|
||||||
f, err := open(path, flag, perm)
|
f, err := open(path, flag, perm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := lockFile(syscall.Handle(f.Fd()), LOCKFILE_FAIL_IMMEDIATELY); err != nil {
|
if err := lockFile(windows.Handle(f.Fd()), windows.LOCKFILE_FAIL_IMMEDIATELY); err != nil {
|
||||||
f.Close()
|
f.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -58,7 +45,7 @@ func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := lockFile(syscall.Handle(f.Fd()), 0); err != nil {
|
if err := lockFile(windows.Handle(f.Fd()), 0); err != nil {
|
||||||
f.Close()
|
f.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -95,32 +82,17 @@ func open(path string, flag int, perm os.FileMode) (*os.File, error) {
|
|||||||
return os.NewFile(uintptr(fd), path), nil
|
return os.NewFile(uintptr(fd), path), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lockFile(fd syscall.Handle, flags uint32) error {
|
func lockFile(fd windows.Handle, flags uint32) error {
|
||||||
var flag uint32 = LOCKFILE_EXCLUSIVE_LOCK
|
if fd == windows.InvalidHandle {
|
||||||
flag |= flags
|
|
||||||
if fd == syscall.InvalidHandle {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := lockFileEx(fd, flag, 1, 0, &syscall.Overlapped{})
|
err := windows.LockFileEx(fd, flags|windows.LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &windows.Overlapped{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else if err.Error() == errLocked.Error() {
|
} else if err.Error() == errLocked.Error() {
|
||||||
return ErrLocked
|
return ErrLocked
|
||||||
} else if err != errLockViolation {
|
} else if err != windows.ERROR_LOCK_VIOLATION {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lockFileEx(h syscall.Handle, flags, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
|
|
||||||
var reserved uint32 = 0
|
|
||||||
r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = error(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user