// Copyright 2026 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT //go:build windows package lock import ( "errors" "os" "golang.org/x/sys/windows" ) // tryLock opens (creating if needed) the lock file and takes a non-blocking // exclusive lock on it via LockFileEx. The returned release closes the file, // which drops the lock; Windows also drops it when the process exits. func tryLock(path string) (func() error, error) { f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600) if err != nil { return nil, err } handle := windows.Handle(f.Fd()) overlapped := new(windows.Overlapped) if err := windows.LockFileEx(handle, windows.LOCKFILE_EXCLUSIVE_LOCK|windows.LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, overlapped); err != nil { _ = f.Close() if errors.Is(err, windows.ERROR_LOCK_VIOLATION) { return nil, ErrLocked } return nil, err } return func() error { _ = windows.UnlockFileEx(handle, 0, 1, 0, overlapped) return f.Close() }, nil }