github.com/searKing/golang/go@v1.2.117/sync/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  // Copied from go/gc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go
     6  
     7  //go:build windows
     8  
     9  package filelock
    10  
    11  import (
    12  	"io/fs"
    13  
    14  	"golang.org/x/sys/windows"
    15  )
    16  
    17  type lockType uint32
    18  
    19  const (
    20  	readLock  lockType = 0
    21  	writeLock lockType = windows.LOCKFILE_EXCLUSIVE_LOCK
    22  )
    23  
    24  const (
    25  	reserved = 0
    26  	allBytes = ^uint32(0)
    27  )
    28  
    29  func lock(f File, lt lockType, try bool) error {
    30  	// Per https://golang.org/issue/19098, “Programs currently expect the Fd
    31  	// method to return a handle that uses ordinary synchronous I/O.”
    32  	// However, LockFileEx still requires an OVERLAPPED structure,
    33  	// which contains the file offset of the beginning of the lock range.
    34  	// We want to lock the entire file, so we leave the offset as zero.
    35  	ol := new(windows.Overlapped)
    36  	if try {
    37  		lt |= windows.LOCKFILE_FAIL_IMMEDIATELY
    38  	}
    39  
    40  	err := windows.LockFileEx(windows.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol)
    41  	if err != nil {
    42  		return &fs.PathError{
    43  			Op:   lt.String(),
    44  			Path: f.Name(),
    45  			Err:  err,
    46  		}
    47  	}
    48  	return nil
    49  }
    50  
    51  func unlock(f File) error {
    52  	ol := new(windows.Overlapped)
    53  	err := windows.UnlockFileEx(windows.Handle(f.Fd()), reserved, allBytes, allBytes, ol)
    54  	if err != nil {
    55  		return &fs.PathError{
    56  			Op:   "Unlock",
    57  			Path: f.Name(),
    58  			Err:  err,
    59  		}
    60  	}
    61  	return nil
    62  }