github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/go/lockedfile/internal/filelock/filelock.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  // Package filelock provides a platform-independent API for advisory file
     6  // locking. Calls to functions in this package on platforms that do not support
     7  // advisory locks will return errors for which IsNotSupported returns true.
     8  package filelock
     9  
    10  import (
    11  	"errors"
    12  	"io/fs"
    13  )
    14  
    15  // A File provides the minimal set of methods required to lock an open file.
    16  // File implementations must be usable as map keys.
    17  // The usual implementation is *os.File.
    18  type File interface {
    19  	// Name returns the name of the file.
    20  	Name() string
    21  
    22  	// Fd returns a valid file descriptor.
    23  	// (If the File is an *os.File, it must not be closed.)
    24  	Fd() uintptr
    25  
    26  	// Stat returns the FileInfo structure describing file.
    27  	Stat() (fs.FileInfo, error)
    28  }
    29  
    30  // Lock places an advisory write lock on the file, blocking until it can be
    31  // locked.
    32  //
    33  // If Lock returns nil, no other process will be able to place a read or write
    34  // lock on the file until this process exits, closes f, or calls Unlock on it.
    35  //
    36  // If f's descriptor is already read- or write-locked, the behavior of Lock is
    37  // unspecified.
    38  //
    39  // Closing the file may or may not release the lock promptly. Callers should
    40  // ensure that Unlock is always called when Lock succeeds.
    41  func Lock(f File) error {
    42  	return lock(f, writeLock)
    43  }
    44  
    45  // RLock places an advisory read lock on the file, blocking until it can be locked.
    46  //
    47  // If RLock returns nil, no other process will be able to place a write lock on
    48  // the file until this process exits, closes f, or calls Unlock on it.
    49  //
    50  // If f is already read- or write-locked, the behavior of RLock is unspecified.
    51  //
    52  // Closing the file may or may not release the lock promptly. Callers should
    53  // ensure that Unlock is always called if RLock succeeds.
    54  func RLock(f File) error {
    55  	return lock(f, readLock)
    56  }
    57  
    58  // Unlock removes an advisory lock placed on f by this process.
    59  //
    60  // The caller must not attempt to unlock a file that is not locked.
    61  func Unlock(f File) error {
    62  	return unlock(f)
    63  }
    64  
    65  // String returns the name of the function corresponding to lt
    66  // (Lock, RLock, or Unlock).
    67  func (lt lockType) String() string {
    68  	switch lt {
    69  	case readLock:
    70  		return "RLock"
    71  	case writeLock:
    72  		return "Lock"
    73  	default:
    74  		return "Unlock"
    75  	}
    76  }
    77  
    78  // IsNotSupported returns a boolean indicating whether the error is known to
    79  // report that a function is not supported (possibly for a specific input).
    80  // It is satisfied by errors.ErrUnsupported as well as some syscall errors.
    81  func IsNotSupported(err error) bool {
    82  	return errors.Is(err, errors.ErrUnsupported)
    83  }