From c26657bafa23f0a5fd06a6006a36cc976a3faab4 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 14 Dec 2019 11:31:14 -0500 Subject: [PATCH] Use synchronized MastodonCache to prevent race condition crashes --- Tusker/MastodonCache.swift | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/Tusker/MastodonCache.swift b/Tusker/MastodonCache.swift index 98ea5a37d3..5d888f284d 100644 --- a/Tusker/MastodonCache.swift +++ b/Tusker/MastodonCache.swift @@ -12,10 +12,10 @@ import Pachyderm class MastodonCache { - private static var statuses = [String: Status]() - private static var accounts = [String: Account]() - private static var relationships = [String: Relationship]() - private static var notifications = [String: Pachyderm.Notification]() + private static var statuses = CachedDictionary(name: "Statuses") + private static var accounts = CachedDictionary(name: "Accounts") + private static var relationships = CachedDictionary(name: "Relationships") + private static var notifications = CachedDictionary(name: "Notifications") static let statusSubject = PassthroughSubject() static let accountSubject = PassthroughSubject() @@ -134,3 +134,29 @@ class MastodonCache { } } + +class CachedDictionary { + private let name: String + private var dict = [String: Value]() + private let queue: DispatchQueue + + init(name: String) { + self.name = name + self.queue = DispatchQueue(label: "CachedDictionary (\(name)) Coordinator", attributes: .concurrent) + } + + subscript(key: String) -> Value? { + get { + var result: Value? = nil + queue.sync { + result = dict[key] + } + return result + } + set(value) { + queue.async(flags: .barrier) { + self.dict[key] = value + } + } + } +}