Skip to content

Commit 5449a25

Browse files
authored
Merge pull request #1705 from vlm/filelock-fix
FileLock fixes
2 parents 43ef824 + 026cb0e commit 5449a25

File tree

1 file changed

+14
-17
lines changed

1 file changed

+14
-17
lines changed

Sources/Basic/Lock.swift

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,39 +33,33 @@ enum ProcessLockError: Swift.Error {
3333

3434
/// Provides functionality to aquire a lock on a file via POSIX's flock() method.
3535
/// 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.
3737
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-
4438
/// File descriptor to the lock file.
45-
private var fd: Int32?
39+
private var fd: CInt?
4640

4741
/// Path to the lock file.
48-
private var lockFile: AbsolutePath {
49-
return cachePath.appending(component: name + ".lock")
50-
}
42+
private let lockFile: AbsolutePath
5143

5244
/// Create an instance of process lock with a name and the path where
5345
/// the lock file can be created.
5446
///
5547
/// Note: The cache path should be a valid directory.
5648
public init(name: String, cachePath: AbsolutePath) {
57-
self.name = name
58-
self.cachePath = cachePath
49+
self.lockFile = cachePath.appending(component: name + ".lock")
5950
}
6051

6152
/// Try to aquire a lock. This method will block until lock the already aquired by other process.
6253
///
6354
/// Note: This method can throw if underlying POSIX methods fail.
6455
public func lock() throws {
6556
// 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
6963
}
7064
// Aquire lock on the file.
7165
while true {
@@ -82,8 +76,11 @@ public final class FileLock {
8276
public func unlock() {
8377
guard let fd = fd else { return }
8478
flock(fd, LOCK_UN)
79+
}
80+
81+
deinit {
82+
guard let fd = fd else { return }
8583
close(fd)
86-
self.fd = nil
8784
}
8885

8986
/// Execute the given block while holding the lock.

0 commit comments

Comments
 (0)