From f34b04c681f40025241b31da90de1206770cb413 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 19 Oct 2020 08:47:33 -0700 Subject: [PATCH] Make DiagnosticEngine thread safe This allows consumers to emit diagnostics from multiple threads. Primarily motivated by https://github.com/apple/swift-format/pull/117 --- Sources/SwiftSyntax/DiagnosticEngine.swift | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftSyntax/DiagnosticEngine.swift b/Sources/SwiftSyntax/DiagnosticEngine.swift index c85bf4b1e6f..e3727811ec8 100644 --- a/Sources/SwiftSyntax/DiagnosticEngine.swift +++ b/Sources/SwiftSyntax/DiagnosticEngine.swift @@ -21,10 +21,39 @@ public class DiagnosticEngine { public init() { } + private var consumersQueue = DispatchQueue( + label: "com.apple.SwiftSyntax.DiagnosticEngine.consumers", attributes: .concurrent) + private var _consumers = [DiagnosticConsumer]() /// The list of consumers of the diagnostic passing through this engine. - internal var consumers = [DiagnosticConsumer]() + private var consumers: [DiagnosticConsumer] { + get { + consumersQueue.sync { + _consumers + } + } - public private(set) var diagnostics = [Diagnostic]() + set { + consumersQueue.async(flags: .barrier) { + self._consumers = newValue + } + } + } + + private var diagnosticsQueue = DispatchQueue( + label: "com.apple.SwiftSyntax.DiagnosticEngine.diagnostics", attributes: .concurrent) + private var _diagnostics = [Diagnostic]() + public private(set) var diagnostics: [Diagnostic] { + get { + diagnosticsQueue.sync { + _diagnostics + } + } + set { + diagnosticsQueue.async(flags: .barrier) { + self._diagnostics = newValue + } + } + } internal var needsLineColumn: Bool { // Check if any consumer is interested in line and column.