返回 DeepSeek-Reasonix
lock_windows.go
根目录 / internal / filelock / lock_windows.go
1 //go:build windows
2
3 package filelock
4
5 import (
6 "errors"
7 "os"
8
9 "golang.org/x/sys/windows"
10 )
11
12 func tryLockFile(path string) (func(), error) {
13 return tryLockFileMode(path, ModeExclusive)
14 }
15
16 func tryLockFileMode(path string, mode Mode) (func(), error) {
17 f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
18 if err != nil {
19 if errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
20 return nil, ErrHeld
21 }
22 return nil, err
23 }
24 handle := windows.Handle(f.Fd())
25 var overlapped windows.Overlapped
26 flags := uint32(windows.LOCKFILE_EXCLUSIVE_LOCK | windows.LOCKFILE_FAIL_IMMEDIATELY)
27 if mode == ModeShared {
28 flags = uint32(windows.LOCKFILE_FAIL_IMMEDIATELY)
29 }
30 if err := windows.LockFileEx(handle, flags, 0, 1, 0, &overlapped); err != nil {
31 _ = f.Close()
32 if errors.Is(err, windows.ERROR_LOCK_VIOLATION) || errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
33 return nil, ErrHeld
34 }
35 return nil, err
36 }
37 return func() {
38 _ = windows.UnlockFileEx(handle, 0, 1, 0, &overlapped)
39 _ = f.Close()
40 }, nil
41 }
42
42 lines GO