diff --git a/state/local.go b/state/local.go index 3a9e40c43..b4029267e 100644 --- a/state/local.go +++ b/state/local.go @@ -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 { diff --git a/state/local_lock_windows.go b/state/local_lock_windows.go index 6d3b5e2cd..01738c9bb 100644 --- a/state/local_lock_windows.go +++ b/state/local_lock_windows.go @@ -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) {