Fix race condition in TulsiProcessRunner
- In rare cases when the `HeadlessXcodeProjectGenerator` tries to fetch
workspace information right as the `TulsiProjectInfoExtractor` tried
to do the same, a crash could occur while two threads tried to
reference the same environment dictionary
PiperOrigin-RevId: 294524286
diff --git a/src/TulsiGenerator/TulsiProcessRunner.swift b/src/TulsiGenerator/TulsiProcessRunner.swift
index 3846a52..215b67d 100644
--- a/src/TulsiGenerator/TulsiProcessRunner.swift
+++ b/src/TulsiGenerator/TulsiProcessRunner.swift
@@ -28,21 +28,22 @@
return environment
}()
+ /// Used to synchronize access to `defaultEnvironment`.
+ private static let semaphore = DispatchSemaphore(value: 1)
+
/// Prepares a Process using the given launch binary with the given arguments that will collect
/// output and passing it to a terminationHandler.
static func createProcess(_ launchPath: String,
arguments: [String],
- environment: [String: String]? = nil,
+ environment: [String: String] = [:],
messageLogger: LocalizedMessageLogger? = nil,
loggingIdentifier: String? = nil,
terminationHandler: @escaping CompletionHandler) -> Process {
-
- var env = defaultEnvironment
- if let environment = environment {
- for (key, value) in environment {
- env[key] = value
- }
+ _ = TulsiProcessRunner.semaphore.wait(timeout: DispatchTime.distantFuture)
+ let env = environment.merging(defaultEnvironment) { (current, _) in
+ return current
}
+ TulsiProcessRunner.semaphore.signal()
return ProcessRunner.createProcess(launchPath,
arguments: arguments,
environment: env,