aboutsummaryrefslogtreecommitdiff
path: root/locker_win.go
blob: ec144009b1eb4cfb82bb36681fb90061ef4a8df5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//go:build windows
// +build windows

package fqueue

import (
	"syscall"
	"unsafe"
)

var (
	modkernel32      = syscall.NewLazyDLL("kernel32.dll")
	procLockFileEx   = modkernel32.NewProc("LockFileEx")
	procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
)

func lock(fd int, wait bool) error {
	handle := syscall.Handle(fd)
	var flags uint32 = 0x00000002 // LOCKFILE_EXCLUSIVE_LOCK
	if !wait {
		flags |= 0x00000001 // LOCKFILE_FAIL_IMMEDIATELY
	}

	var overlapped syscall.Overlapped
	r, _, err := procLockFileEx.Call(
		uintptr(handle),
		uintptr(flags),
		0,
		uintptr(^uint32(0)), // максимальное количество байт
		uintptr(^uint32(0)),
		uintptr(unsafe.Pointer(&overlapped)),
	)
	if r == 0 {
		return err
	}
	return nil
}

func unlock(fd int) error {
	handle := syscall.Handle(fd)
	var overlapped syscall.Overlapped

	r, _, err := procUnlockFileEx.Call(
		uintptr(handle),
		0,
		uintptr(^uint32(0)),
		uintptr(^uint32(0)),
		uintptr(unsafe.Pointer(&overlapped)),
	)
	if r == 0 {
		return err
	}
	return nil
}