Skip to content

Commit b1fc0c0

Browse files
authored
Fix TSAN failure in FileAccessLogger (#92)
### Motivation Fix #91, a TSAN failure in FileAccessLogger. ### Modifications Migrated from a manual locked state machine to a lazy static let. ### Result Fixed the TSAN failure plus simplified the code. ### Test Plan Manually tested by rerunning the console-kit tests with the fixed version, TSAN failure doesn't happen anymore.
1 parent af88704 commit b1fc0c0

File tree

1 file changed

+12
-36
lines changed

1 file changed

+12
-36
lines changed

Sources/Configuration/AccessReporters/FileAccessLogger.swift

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,18 @@ public final class FileAccessLogger: Sendable {
150150
}
151151
}
152152

153-
/// The internal representation of the shared instance.
154-
private enum SharedStorage {
155-
156-
/// The instance hasn't been requested yet.
157-
case uninitialized
158-
159-
/// Failed to create a file access logger, the environment variable might be malformed.
160-
case initializationFailed(any Error)
161-
162-
/// Successfully initialized (or skipped) the logger and stored the result.
163-
case initialized(FileAccessLogger?)
164-
}
165-
166153
/// The locked storage for the singleton instance managed by the `detectedFromEnvironment()` method.
167-
private static let shared: Mutex<SharedStorage> = .init(.uninitialized)
154+
private static let shared: Result<FileAccessLogger?, any Error> = {
155+
Result {
156+
let newInstance: FileAccessLogger?
157+
if let filePathString = ProcessInfo.processInfo.environment["CONFIG_ACCESS_LOG_FILE"] {
158+
newInstance = try FileAccessLogger(filePath: FilePath(filePathString))
159+
} else {
160+
newInstance = nil
161+
}
162+
return newInstance
163+
}
164+
}()
168165

169166
/// Returns a shared file access logger instance controlled by environment variables.
170167
///
@@ -175,28 +172,7 @@ public final class FileAccessLogger: Sendable {
175172
/// - Returns: A file access logger if the environment variable is set, nil otherwise.
176173
/// - Throws: An error if the environment variable is set but the logger cannot be created.
177174
internal static func detectedFromEnvironment() throws -> FileAccessLogger? {
178-
try shared.withLock { shared in
179-
switch shared {
180-
case .initialized(let existing):
181-
return existing
182-
case .initializationFailed(let error):
183-
throw error
184-
case .uninitialized:
185-
do {
186-
let newInstance: FileAccessLogger?
187-
if let filePathString = ProcessInfo.processInfo.environment["CONFIG_ACCESS_LOG_FILE"] {
188-
newInstance = try FileAccessLogger(filePath: FilePath(filePathString))
189-
} else {
190-
newInstance = nil
191-
}
192-
shared = .initialized(newInstance)
193-
return newInstance
194-
} catch {
195-
shared = .initializationFailed(error)
196-
throw error
197-
}
198-
}
199-
}
175+
try shared.get()
200176
}
201177
}
202178

0 commit comments

Comments
 (0)