@@ -33,39 +33,33 @@ enum ProcessLockError: Swift.Error {
33
33
34
34
/// Provides functionality to aquire a lock on a file via POSIX's flock() method.
35
35
/// It can be used for things like serializing concurrent mutations on a shared resource
36
- /// by mutiple instances of a process.
36
+ /// by mutiple instances of a process. The `FileLock` is not thread-safe.
37
37
public final class FileLock {
38
- /// The name of the lock, used in filename of the lock file.
39
- let name : String
40
-
41
- /// The directory where the lock file should be created.
42
- let cachePath : AbsolutePath
43
-
44
38
/// File descriptor to the lock file.
45
- private var fd : Int32 ?
39
+ private var fd : CInt ?
46
40
47
41
/// Path to the lock file.
48
- private var lockFile : AbsolutePath {
49
- return cachePath. appending ( component: name + " .lock " )
50
- }
42
+ private let lockFile : AbsolutePath
51
43
52
44
/// Create an instance of process lock with a name and the path where
53
45
/// the lock file can be created.
54
46
///
55
47
/// Note: The cache path should be a valid directory.
56
48
public init ( name: String , cachePath: AbsolutePath ) {
57
- self . name = name
58
- self . cachePath = cachePath
49
+ self . lockFile = cachePath. appending ( component: name + " .lock " )
59
50
}
60
51
61
52
/// Try to aquire a lock. This method will block until lock the already aquired by other process.
62
53
///
63
54
/// Note: This method can throw if underlying POSIX methods fail.
64
55
public func lock( ) throws {
65
56
// Open the lock file.
66
- fd = SPMLibc . open ( lockFile. asString, O_WRONLY | O_CREAT, 0644 )
67
- if fd == - 1 {
68
- throw FileSystemError ( errno: errno)
57
+ if fd == nil {
58
+ let fd = SPMLibc . open ( lockFile. asString, O_WRONLY | O_CREAT | O_CLOEXEC, 0o666 )
59
+ if fd == - 1 {
60
+ throw FileSystemError ( errno: errno)
61
+ }
62
+ self . fd = fd
69
63
}
70
64
// Aquire lock on the file.
71
65
while true {
@@ -82,8 +76,11 @@ public final class FileLock {
82
76
public func unlock( ) {
83
77
guard let fd = fd else { return }
84
78
flock ( fd, LOCK_UN)
79
+ }
80
+
81
+ deinit {
82
+ guard let fd = fd else { return }
85
83
close ( fd)
86
- self . fd = nil
87
84
}
88
85
89
86
/// Execute the given block while holding the lock.
0 commit comments