返回 DeepSeek-Reasonix
process_windows.go
根目录 / internal / mcplaunch / process_windows.go
1 //go:build windows
2
3 package mcplaunch
4
5 import (
6 "errors"
7
8 "golang.org/x/sys/windows"
9 )
10
11 const launchLockStillActiveExitCode = 259
12
13 func launchLockProcessAlive(pid int) bool {
14 if pid <= 0 {
15 return false
16 }
17 handle, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
18 if err != nil {
19 // Access denied still proves the process exists. Treating it as stale
20 // would let a less-privileged waiter steal a live writer's lock.
21 return err == windows.ERROR_ACCESS_DENIED
22 }
23 defer windows.CloseHandle(handle)
24 var code uint32
25 return windows.GetExitCodeProcess(handle, &code) == nil && code == launchLockStillActiveExitCode
26 }
27
28 // launchLockContention reports transient Windows name/handle races while one
29 // owner removes the exclusive-create lock and another tries to create it.
30 // OpenFile can surface those races as access or sharing violations instead of
31 // os.ErrExist, so callers must retry them within the normal lock deadline.
32 func launchLockContention(err error) bool {
33 return errors.Is(err, windows.ERROR_ACCESS_DENIED) ||
34 errors.Is(err, windows.ERROR_SHARING_VIOLATION)
35 }
36
36 lines GO