Skip to content

Commit 19184ad

Browse files
committed
Bring back "Lock scratch directory during tool execution"
This reverts commit e92df2d and brings back the changes from #7269.
1 parent 3e8328e commit 19184ad

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

Sources/Basics/FileSystem/FileSystem+Extensions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ extension FileSystem {
196196
}
197197

198198
/// Execute the given block while holding the lock.
199-
public func withLock<T>(on path: AbsolutePath, type: FileLock.LockType, _ body: () throws -> T) throws -> T {
200-
try self.withLock(on: path.underlying, type: type, body)
199+
public func withLock<T>(on path: AbsolutePath, type: FileLock.LockType, blocking: Bool = true, _ body: () throws -> T) throws -> T {
200+
try self.withLock(on: path.underlying, type: type, blocking: blocking, body)
201201
}
202202

203203
/// Returns any known item replacement directories for a given path. These may be used by platform-specific

Sources/CoreCommands/SwiftTool.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import func TSCBasic.exec
4242
import protocol TSCBasic.OutputByteStream
4343
import class TSCBasic.Process
4444
import enum TSCBasic.ProcessEnv
45+
import enum TSCBasic.ProcessLockError
4546
import var TSCBasic.stderrStream
4647
import class TSCBasic.TerminalController
4748
import class TSCBasic.ThreadSafeOutputByteStream
@@ -109,14 +110,27 @@ extension SwiftCommand {
109110
workspaceLoaderProvider: self.workspaceLoaderProvider
110111
)
111112
swiftTool.buildSystemProvider = try buildSystemProvider(swiftTool)
112-
var toolError: Error? = .none
113+
114+
// Try a non-blocking lock first so that we can inform the user about an already running SwiftPM.
113115
do {
114-
try self.run(swiftTool)
115-
if swiftTool.observabilityScope.errorsReported || swiftTool.executionStatus == .failure {
116-
throw ExitCode.failure
116+
try swiftTool.fileSystem.withLock(on: swiftTool.scratchDirectory, type: .exclusive, blocking: false) {}
117+
} catch let ProcessLockError.unableToAquireLock(errno) {
118+
if errno == EWOULDBLOCK {
119+
swiftTool.outputStream.write("Another instance of SwiftPM is already running using '\(swiftTool.scratchDirectory)', waiting until that process has finished execution...".utf8)
120+
swiftTool.outputStream.flush()
121+
}
122+
}
123+
124+
var toolError: Error? = .none
125+
try swiftTool.fileSystem.withLock(on: swiftTool.scratchDirectory, type: .exclusive) {
126+
do {
127+
try self.run(swiftTool)
128+
if swiftTool.observabilityScope.errorsReported || swiftTool.executionStatus == .failure {
129+
throw ExitCode.failure
130+
}
131+
} catch {
132+
toolError = error
117133
}
118-
} catch {
119-
toolError = error
120134
}
121135

122136
// wait for all observability items to process

0 commit comments

Comments
 (0)