github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/go/lockedfile/internal/filelock/filelock_windows.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build windows
     6  
     7  package filelock
     8  
     9  import (
    10  	"io/fs"
    11  	"syscall"
    12  
    13  	"github.com/go-asm/go/syscall/windows"
    14  )
    15  
    16  type lockType uint32
    17  
    18  const (
    19  	readLock  lockType = 0
    20  	writeLock lockType = windows.LOCKFILE_EXCLUSIVE_LOCK
    21  )
    22  
    23  const (
    24  	reserved = 0
    25  	allBytes = ^uint32(0)
    26  )
    27  
    28  func lock(f File, lt lockType) error {
    29  	// Per https://golang.org/issue/19098, “Programs currently expect the Fd
    30  	// method to return a handle that uses ordinary synchronous I/O.”
    31  	// However, LockFileEx still requires an OVERLAPPED structure,
    32  	// which contains the file offset of the beginning of the lock range.
    33  	// We want to lock the entire file, so we leave the offset as zero.
    34  	ol := new(syscall.Overlapped)
    35  
    36  	err := windows.LockFileEx(syscall.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol)
    37  	if err != nil {
    38  		return &fs.PathError{
    39  			Op:   lt.String(),
    40  			Path: f.Name(),
    41  			Err:  err,
    42  		}
    43  	}
    44  	return nil
    45  }
    46  
    47  func unlock(f File) error {
    48  	ol := new(syscall.Overlapped)
    49  	err := windows.UnlockFileEx(syscall.Handle(f.Fd()), reserved, allBytes, allBytes, ol)
    50  	if err != nil {
    51  		return &fs.PathError{
    52  			Op:   "Unlock",
    53  			Path: f.Name(),
    54  			Err:  err,
    55  		}
    56  	}
    57  	return nil
    58  }