From 17e770c77d878576fc56b06f414498748c8a2e0c Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 19 Oct 2020 08:49:31 -0700 Subject: [PATCH] Make Rule nameCache thread safe --- Sources/SwiftFormatCore/Rule.swift | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftFormatCore/Rule.swift b/Sources/SwiftFormatCore/Rule.swift index d13a877d4..887092f8e 100644 --- a/Sources/SwiftFormatCore/Rule.swift +++ b/Sources/SwiftFormatCore/Rule.swift @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +import Foundation + /// A Rule is a linting or formatting pass that executes in a given context. public protocol Rule { /// The context in which the rule is executed. @@ -26,16 +28,26 @@ public protocol Rule { } fileprivate var nameCache = [ObjectIdentifier: String]() +fileprivate var nameCacheQueue = DispatchQueue( + label: "com.apple.SwiftFormat.NameCache", attributes: .concurrent) extension Rule { /// By default, the `ruleName` is just the name of the implementing rule class. public static var ruleName: String { let identifier = ObjectIdentifier(self) - if let cachedName = nameCache[identifier] { + let cachedName = nameCacheQueue.sync { + nameCache[identifier] + } + + if let cachedName = cachedName { return cachedName } + let name = String("\(self)".split(separator: ".").last!) - nameCache[identifier] = name + nameCacheQueue.async(flags: .barrier) { + nameCache[identifier] = name + } + return name } }