github.com/searKing/golang/go@v1.2.117/sync/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 // 9 // Copied from go/gc/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go 10 11 package filelock 12 13 import ( 14 "errors" 15 "io/fs" 16 "os" 17 ) 18 19 // A File provides the minimal set of methods required to lock an open file. 20 // File implementations must be usable as map keys. 21 // The usual implementation is *os.File. 22 type File interface { 23 // Name returns the name of the file. 24 Name() string 25 26 // Fd returns a valid file descriptor. 27 // (If the File is an *os.File, it must not be closed.) 28 Fd() uintptr 29 30 // Stat returns the FileInfo structure describing file. 31 Stat() (fs.FileInfo, error) 32 } 33 34 // Lock places an advisory write lock on the file, blocking until it can be 35 // locked. 36 // 37 // If Lock returns nil, no other process will be able to place a read or write 38 // lock on the file until this process exits, closes f, or calls Unlock on it. 39 // 40 // If f's descriptor is already read- or write-locked, the behavior of Lock is 41 // unspecified. 42 // 43 // Closing the file may or may not release the lock promptly. Callers should 44 // ensure that Unlock is always called when Lock succeeds. 45 func Lock(f File) error { 46 return lock(f, writeLock, false) 47 } 48 49 // TryLock tries to lock rw for writing and reports whether it succeeded. 50 // 51 // Note that while correct uses of TryLock do exist, they are rare, 52 // and use of TryLock is often a sign of a deeper problem 53 // in a particular use of mutexes. 54 func TryLock(f File) (bool, error) { 55 err := lock(f, writeLock, true) 56 if err != nil { 57 if os.IsTimeout(err) { 58 return false, nil 59 } 60 return false, err 61 } 62 return true, nil 63 } 64 65 // RLock places an advisory read lock on the file, blocking until it can be locked. 66 // 67 // If RLock returns nil, no other process will be able to place a write lock on 68 // the file until this process exits, closes f, or calls Unlock on it. 69 // 70 // If f is already read- or write-locked, the behavior of RLock is unspecified. 71 // 72 // Closing the file may or may not release the lock promptly. Callers should 73 // ensure that Unlock is always called if RLock succeeds. 74 func RLock(f File) error { 75 return lock(f, readLock, false) 76 } 77 78 // TryRLock tries to lock rw for reading and reports whether it succeeded. 79 // 80 // Note that while correct uses of TryRLock do exist, they are rare, 81 // and use of TryRLock is often a sign of a deeper problem 82 // in a particular use of mutexes. 83 func TryRLock(f File) (bool, error) { 84 err := lock(f, readLock, true) 85 if err != nil { 86 if os.IsTimeout(err) { 87 return false, nil 88 } 89 return false, err 90 } 91 return true, nil 92 } 93 94 // Unlock removes an advisory lock placed on f by this process. 95 // 96 // The caller must not attempt to unlock a file that is not locked. 97 func Unlock(f File) error { 98 return unlock(f) 99 } 100 101 // String returns the name of the function corresponding to lt 102 // (Lock, RLock, or Unlock). 103 func (lt lockType) String() string { 104 switch lt { 105 case readLock: 106 return "RLock" 107 case writeLock: 108 return "Lock" 109 default: 110 return "Unlock" 111 } 112 } 113 114 // IsNotSupported returns a boolean indicating whether the error is known to 115 // report that a function is not supported (possibly for a specific input). 116 // It is satisfied by errors.ErrUnsupported as well as some syscall errors. 117 func IsNotSupported(err error) bool { 118 return errors.Is(err, errors.ErrUnsupported) 119 }