github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/state/local_lock_windows.go (about) 1 // +build windows 2 3 package state 4 5 import ( 6 "math" 7 "syscall" 8 "unsafe" 9 ) 10 11 var ( 12 modkernel32 = syscall.NewLazyDLL("kernel32.dll") 13 procLockFileEx = modkernel32.NewProc("LockFileEx") 14 procCreateEventW = modkernel32.NewProc("CreateEventW") 15 ) 16 17 const ( 18 // dwFlags defined for LockFileEx 19 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx 20 _LOCKFILE_FAIL_IMMEDIATELY = 1 21 _LOCKFILE_EXCLUSIVE_LOCK = 2 22 ) 23 24 func (s *LocalState) lock() error { 25 // even though we're failing immediately, an overlapped event structure is 26 // required 27 ol, err := newOverlapped() 28 if err != nil { 29 return err 30 } 31 defer syscall.CloseHandle(ol.HEvent) 32 33 return lockFileEx( 34 syscall.Handle(s.stateFileOut.Fd()), 35 _LOCKFILE_EXCLUSIVE_LOCK|_LOCKFILE_FAIL_IMMEDIATELY, 36 0, // reserved 37 0, // bytes low 38 math.MaxUint32, // bytes high 39 ol, 40 ) 41 } 42 43 func (s *LocalState) unlock() error { 44 // the file is closed in Unlock 45 return nil 46 } 47 48 func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) { 49 r1, _, e1 := syscall.Syscall6( 50 procLockFileEx.Addr(), 51 6, 52 uintptr(h), 53 uintptr(flags), 54 uintptr(reserved), 55 uintptr(locklow), 56 uintptr(lockhigh), 57 uintptr(unsafe.Pointer(ol)), 58 ) 59 if r1 == 0 { 60 if e1 != 0 { 61 err = error(e1) 62 } else { 63 err = syscall.EINVAL 64 } 65 } 66 return 67 } 68 69 // newOverlapped creates a structure used to track asynchronous 70 // I/O requests that have been issued. 71 func newOverlapped() (*syscall.Overlapped, error) { 72 event, err := createEvent(nil, true, false, nil) 73 if err != nil { 74 return nil, err 75 } 76 return &syscall.Overlapped{HEvent: event}, nil 77 } 78 79 func createEvent(sa *syscall.SecurityAttributes, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) { 80 var _p0 uint32 81 if manualReset { 82 _p0 = 1 83 } 84 var _p1 uint32 85 if initialState { 86 _p1 = 1 87 } 88 89 r0, _, e1 := syscall.Syscall6( 90 procCreateEventW.Addr(), 91 4, 92 uintptr(unsafe.Pointer(sa)), 93 uintptr(_p0), 94 uintptr(_p1), 95 uintptr(unsafe.Pointer(name)), 96 0, 97 0, 98 ) 99 handle = syscall.Handle(r0) 100 if handle == syscall.InvalidHandle { 101 if e1 != 0 { 102 err = error(e1) 103 } else { 104 err = syscall.EINVAL 105 } 106 } 107 return 108 }