fix windows locking

Don't create a new windows handle for the lock.
This commit is contained in:
James Bardin 2017-02-17 10:53:24 -05:00
parent c0dda6a7b3
commit a4283d23f6
2 changed files with 7 additions and 45 deletions

View File

@ -147,6 +147,10 @@ func (s *LocalState) Lock(info *LockInfo) (string, error) {
}
}
if s.lockID != "" {
return "", fmt.Errorf("state %q already locked", s.stateFileOut.Name())
}
if err := s.lock(); err != nil {
info, infoErr := s.lockInfo()
if infoErr != nil {

View File

@ -4,23 +4,14 @@ package state
import (
"math"
"os"
"sync"
"syscall"
"unsafe"
)
type stateLock struct {
handle syscall.Handle
}
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procLockFileEx = modkernel32.NewProc("LockFileEx")
procCreateEventW = modkernel32.NewProc("CreateEventW")
lockedFilesMu sync.Mutex
lockedFiles = map[*os.File]syscall.Handle{}
)
const (
@ -31,31 +22,6 @@ const (
)
func (s *LocalState) lock() error {
lockedFilesMu.Lock()
defer lockedFilesMu.Unlock()
name, err := syscall.UTF16PtrFromString(s.PathOut)
if err != nil {
return err
}
handle, err := syscall.CreateFile(
name,
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
// since this file is already open in out process, we need shared
// access here for this call.
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,
nil,
syscall.OPEN_EXISTING,
syscall.FILE_ATTRIBUTE_NORMAL,
0,
)
if err != nil {
return err
}
lockedFiles[s.stateFileOut] = handle
// even though we're failing immediately, an overlapped event structure is
// required
ol, err := newOverlapped()
@ -65,7 +31,7 @@ func (s *LocalState) lock() error {
defer syscall.CloseHandle(ol.HEvent)
return lockFileEx(
handle,
syscall.Handle(s.stateFileOut.Fd()),
_LOCKFILE_EXCLUSIVE_LOCK|_LOCKFILE_FAIL_IMMEDIATELY,
0, // reserved
0, // bytes low
@ -75,16 +41,8 @@ func (s *LocalState) lock() error {
}
func (s *LocalState) unlock() error {
lockedFilesMu.Lock()
defer lockedFilesMu.Unlock()
handle, ok := lockedFiles[s.stateFileOut]
if !ok {
// we allow multiple Unlock calls
return nil
}
delete(lockedFiles, s.stateFileOut)
return syscall.Close(handle)
// the file is closed in Unlock
return nil
}
func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {