12
12
// To avoid unlocking files prematurely when the same file is opened through different descriptors,
13
13
// we allow only one read-lock at a time.
14
14
//
15
- // This code is adapted from the Go package:
16
- // cmd/go/internal/lockedfile/internal/filelock
15
+ // This code is adapted from the Go package (go.12) :
16
+ // https://github.com/golang/go/blob/release-branch.go1.12/src/ cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
17
17
18
18
//go:build aix || (solaris && !illumos)
19
19
@@ -29,27 +29,45 @@ import (
29
29
"golang.org/x/sys/unix"
30
30
)
31
31
32
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L28
32
33
type lockType int16
33
34
35
+ // String returns the name of the function corresponding to lt
36
+ // (Lock, RLock, or Unlock).
37
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go#L67
38
+ func (lt lockType ) String () string {
39
+ switch lt {
40
+ case readLock :
41
+ return "RLock"
42
+ case writeLock :
43
+ return "Lock"
44
+ default :
45
+ return "Unlock"
46
+ }
47
+ }
48
+
49
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L30-L33
34
50
const (
35
51
readLock lockType = unix .F_RDLCK
36
52
writeLock lockType = unix .F_WRLCK
37
53
)
38
54
39
- type cmdType int
40
-
41
- const (
42
- tryLock cmdType = unix .F_SETLK
43
- waitLock cmdType = unix .F_SETLKW
44
- )
45
-
55
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L35
46
56
type inode = uint64
47
57
58
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L37-L40
48
59
type inodeLock struct {
49
60
owner * Flock
50
61
queue []<- chan * Flock
51
62
}
52
63
64
+ type cmdType int
65
+
66
+ const (
67
+ tryLock cmdType = unix .F_SETLK
68
+ waitLock cmdType = unix .F_SETLKW
69
+ )
70
+
53
71
var (
54
72
mu sync.Mutex
55
73
inodes = map [* Flock ]inode {}
@@ -109,6 +127,7 @@ func (f *Flock) lock(locked *bool, flag lockType) error {
109
127
return nil
110
128
}
111
129
130
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L48
112
131
func (f * Flock ) doLock (cmd cmdType , lt lockType , blocking bool ) (bool , error ) {
113
132
// POSIX locks apply per inode and process,
114
133
// and the lock for an inode is released when *any* descriptor for that inode is closed.
@@ -119,14 +138,15 @@ func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) {
119
138
return false , err
120
139
}
121
140
122
- ino := inode ( fi .Sys ().(* syscall.Stat_t ).Ino )
141
+ ino := fi .Sys ().(* syscall.Stat_t ).Ino
123
142
124
143
mu .Lock ()
125
144
126
145
if i , dup := inodes [f ]; dup && i != ino {
127
146
mu .Unlock ()
128
147
129
148
return false , & os.PathError {
149
+ Op : lt .String (),
130
150
Path : f .Path (),
131
151
Err : errors .New ("inode for file changed since last Lock or RLock" ),
132
152
}
@@ -168,7 +188,7 @@ func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) {
168
188
if err != nil {
169
189
f .doUnlock ()
170
190
171
- if cmd == tryLock && err == unix .EACCES {
191
+ if cmd == tryLock && errors . Is ( err , unix .EACCES ) {
172
192
return false , nil
173
193
}
174
194
@@ -197,6 +217,7 @@ func (f *Flock) Unlock() error {
197
217
return nil
198
218
}
199
219
220
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L163
200
221
func (f * Flock ) doUnlock () (err error ) {
201
222
var owner * Flock
202
223
@@ -288,6 +309,7 @@ func (f *Flock) try(locked *bool, flag lockType) (bool, error) {
288
309
}
289
310
290
311
// setlkw calls FcntlFlock with cmd for the entire file indicated by fd.
312
+ // https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L198
291
313
func setlkw (fd uintptr , cmd cmdType , lt lockType ) error {
292
314
for {
293
315
err := unix .FcntlFlock (fd , int (cmd ), & unix.Flock_t {
@@ -296,7 +318,7 @@ func setlkw(fd uintptr, cmd cmdType, lt lockType) error {
296
318
Start : 0 ,
297
319
Len : 0 , // All bytes.
298
320
})
299
- if err != unix .EINTR {
321
+ if ! errors . Is ( err , unix .EINTR ) {
300
322
return err
301
323
}
302
324
}
0 commit comments