Skip to content

Commit 9057cae

Browse files
authored
Make lazy properties in UserToolchain thread safe (#9356)
1 parent e3cb4a5 commit 9057cae

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

Sources/PackageModel/UserToolchain.swift

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ public final class UserToolchain: Toolchain {
4242
/// An array of paths to search for libraries at link time.
4343
public let librarySearchPaths: [AbsolutePath]
4444

45+
/// Thread-safe cached runtime library paths
46+
private let _runtimeLibraryPaths = ThreadSafeBox<[AbsolutePath]>()
47+
4548
/// An array of paths to use with binaries produced by this toolchain at run time.
46-
public lazy var runtimeLibraryPaths: [AbsolutePath] = {
47-
guard let targetInfo else { return [] }
48-
return (try? Self.computeRuntimeLibraryPaths(targetInfo: targetInfo)) ?? []
49-
}()
49+
public var runtimeLibraryPaths: [AbsolutePath] {
50+
return _runtimeLibraryPaths.memoize {
51+
guard let targetInfo = self.targetInfo else {
52+
return []
53+
}
54+
return (try? Self.computeRuntimeLibraryPaths(targetInfo: targetInfo)) ?? []
55+
}
56+
}
5057

5158
/// Path containing Swift resources for dynamic linking.
5259
public var swiftResourcesPath: AbsolutePath? {
@@ -82,16 +89,29 @@ public final class UserToolchain: Toolchain {
8289
public let targetTriple: Basics.Triple
8390

8491
private let _targetInfo: JSON?
85-
private lazy var targetInfo: JSON? = {
86-
// Only call out to the swift compiler to fetch the target info when necessary
87-
try? _targetInfo ?? Self.getTargetInfo(swiftCompiler: swiftCompilerPath)
88-
}()
92+
93+
/// Thread-safe cached target info that allows for lazy instantiation
94+
private let _cachedTargetInfo = ThreadSafeBox<JSON?>()
95+
96+
private var targetInfo: JSON? {
97+
return _cachedTargetInfo.memoize {
98+
// Only call out to the swift compiler to fetch the target info when necessary
99+
return try? _targetInfo ?? Self.getTargetInfo(swiftCompiler: swiftCompilerPath)
100+
}
101+
}
102+
103+
/// Thread-safe cached swift compiler version that allows for lazy instantiation
104+
private let _swiftCompilerVersion = ThreadSafeBox<String?>()
89105

90106
// A version string that can be used to identify the swift compiler version
91-
public lazy var swiftCompilerVersion: String? = {
92-
guard let targetInfo else { return nil }
93-
return Self.computeSwiftCompilerVersion(targetInfo: targetInfo)
94-
}()
107+
public var swiftCompilerVersion: String? {
108+
return _swiftCompilerVersion.memoize {
109+
guard let targetInfo = self.targetInfo else {
110+
return nil
111+
}
112+
return Self.computeSwiftCompilerVersion(targetInfo: targetInfo)
113+
}
114+
}
95115

96116
/// The list of CPU architectures to build for.
97117
public let architectures: [String]?

0 commit comments

Comments
 (0)