Fix concurrency warnings by marking things as MainActor.

This commit is contained in:
Brent Simmons 2024-04-02 22:26:16 -07:00
parent 3fea0f0758
commit 0949aefa93
10 changed files with 52 additions and 45 deletions

View File

@ -612,6 +612,7 @@ public enum FetchType {
try await delegate.addFeed(for: self, with: feed, to: container) try await delegate.addFeed(for: self, with: feed, to: container)
} }
@discardableResult
public func createFeed(url: String, name: String?, container: Container, validateFeed: Bool) async throws -> Feed { public func createFeed(url: String, name: String?, container: Container, validateFeed: Bool) async throws -> Feed {
try await delegate.createFeed(for: self, url: url, name: name, container: container, validateFeed: validateFeed) try await delegate.createFeed(for: self, url: url, name: name, container: container, validateFeed: validateFeed)

View File

@ -14,11 +14,11 @@ import ArticlesDatabase
import FoundationExtras import FoundationExtras
protocol LocalAccountRefresherDelegate { protocol LocalAccountRefresherDelegate {
func localAccountRefresher(_ refresher: LocalAccountRefresher, requestCompletedFor: Feed) @MainActor func localAccountRefresher(_ refresher: LocalAccountRefresher, requestCompletedFor: Feed)
func localAccountRefresher(_ refresher: LocalAccountRefresher, articleChanges: ArticleChanges, completion: @escaping () -> Void) @MainActor func localAccountRefresher(_ refresher: LocalAccountRefresher, articleChanges: ArticleChanges, completion: @escaping () -> Void)
} }
final class LocalAccountRefresher { @MainActor final class LocalAccountRefresher {
private var completion: (() -> Void)? = nil private var completion: (() -> Void)? = nil
private var isSuspended = false private var isSuspended = false

View File

@ -13,7 +13,7 @@ import AppKitExtras
typealias PasteboardFeedDictionary = [String: String] typealias PasteboardFeedDictionary = [String: String]
struct PasteboardFeed: Hashable { @MainActor struct PasteboardFeed: Hashable {
private struct Key { private struct Key {
static let url = "URL" static let url = "URL"

View File

@ -36,36 +36,42 @@ extension Article: PasteboardWriterOwner {
// MARK: - NSPasteboardWriting // MARK: - NSPasteboardWriting
func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] { nonisolated func writableTypes(for pasteboard: NSPasteboard) -> [NSPasteboard.PasteboardType] {
var types = [ArticlePasteboardWriter.articleUTIType]
if let _ = article.preferredURL { MainActor.assumeIsolated {
types += [.URL] var types = [ArticlePasteboardWriter.articleUTIType]
if let _ = article.preferredURL {
types += [.URL]
}
types += [.string, .html, ArticlePasteboardWriter.articleUTIInternalType]
return types
} }
types += [.string, .html, ArticlePasteboardWriter.articleUTIInternalType]
return types
} }
func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? { nonisolated func pasteboardPropertyList(forType type: NSPasteboard.PasteboardType) -> Any? {
let plist: Any?
switch type { MainActor.assumeIsolated {
case .html: let plist: Any?
return renderedHTML
case .string: switch type {
plist = plainText() case .html:
case .URL: return renderedHTML
return article.preferredLink ?? "" case .string:
case ArticlePasteboardWriter.articleUTIType: plist = plainText()
plist = exportDictionary() case .URL:
case ArticlePasteboardWriter.articleUTIInternalType: return article.preferredLink ?? ""
plist = internalDictionary() case ArticlePasteboardWriter.articleUTIType:
default: plist = exportDictionary()
plist = nil case ArticlePasteboardWriter.articleUTIInternalType:
plist = internalDictionary()
default:
plist = nil
}
return plist
} }
return plist
} }
} }

View File

@ -12,7 +12,7 @@ import Account
protocol SmallIconProvider { protocol SmallIconProvider {
var smallIcon: IconImage? { get } @MainActor var smallIcon: IconImage? { get }
} }
extension Account: SmallIconProvider { extension Account: SmallIconProvider {

View File

@ -12,7 +12,7 @@ import Parser
import Account import Account
import Core import Core
final class ExtensionContainersFile { @MainActor final class ExtensionContainersFile {
private static let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "extensionContainersFile") private static let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "extensionContainersFile")

View File

@ -10,7 +10,7 @@ import Foundation
import Account import Account
protocol SidebarItemIdentifiable { protocol SidebarItemIdentifiable {
var sidebarItemID: SidebarItemIdentifier? { get } @MainActor var sidebarItemID: SidebarItemIdentifier? { get }
} }
enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable { enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable {

View File

@ -11,7 +11,7 @@ import Account
import Articles import Articles
import ArticlesDatabase import ArticlesDatabase
struct SearchFeedDelegate: SmartFeedDelegate { @MainActor struct SearchFeedDelegate: SmartFeedDelegate {
var sidebarItemID: SidebarItemIdentifier? { var sidebarItemID: SidebarItemIdentifier? {
return SidebarItemIdentifier.smartFeed(String(describing: SearchFeedDelegate.self)) return SidebarItemIdentifier.smartFeed(String(describing: SearchFeedDelegate.self))

View File

@ -11,7 +11,7 @@ import Account
import Articles import Articles
import ArticlesDatabase import ArticlesDatabase
struct SearchTimelineFeedDelegate: SmartFeedDelegate { @MainActor struct SearchTimelineFeedDelegate: SmartFeedDelegate {
var sidebarItemID: SidebarItemIdentifier? { var sidebarItemID: SidebarItemIdentifier? {
return SidebarItemIdentifier.smartFeed(String(describing: SearchTimelineFeedDelegate.self)) return SidebarItemIdentifier.smartFeed(String(describing: SearchTimelineFeedDelegate.self))

View File

@ -13,17 +13,17 @@ import Foundation
public protocol DownloadSessionDelegate { public protocol DownloadSessionDelegate {
func downloadSession(_ downloadSession: DownloadSession, requestForRepresentedObject: AnyObject) -> URLRequest? @MainActor func downloadSession(_ downloadSession: DownloadSession, requestForRepresentedObject: AnyObject) -> URLRequest?
func downloadSession(_ downloadSession: DownloadSession, downloadDidCompleteForRepresentedObject: AnyObject, response: URLResponse?, data: Data, error: NSError?, completion: @escaping () -> Void) @MainActor func downloadSession(_ downloadSession: DownloadSession, downloadDidCompleteForRepresentedObject: AnyObject, response: URLResponse?, data: Data, error: NSError?, completion: @escaping () -> Void)
func downloadSession(_ downloadSession: DownloadSession, shouldContinueAfterReceivingData: Data, representedObject: AnyObject) -> Bool @MainActor func downloadSession(_ downloadSession: DownloadSession, shouldContinueAfterReceivingData: Data, representedObject: AnyObject) -> Bool
func downloadSession(_ downloadSession: DownloadSession, didReceiveUnexpectedResponse: URLResponse, representedObject: AnyObject) @MainActor func downloadSession(_ downloadSession: DownloadSession, didReceiveUnexpectedResponse: URLResponse, representedObject: AnyObject)
func downloadSession(_ downloadSession: DownloadSession, didReceiveNotModifiedResponse: URLResponse, representedObject: AnyObject) @MainActor func downloadSession(_ downloadSession: DownloadSession, didReceiveNotModifiedResponse: URLResponse, representedObject: AnyObject)
func downloadSession(_ downloadSession: DownloadSession, didDiscardDuplicateRepresentedObject: AnyObject) @MainActor func downloadSession(_ downloadSession: DownloadSession, didDiscardDuplicateRepresentedObject: AnyObject)
func downloadSessionDidCompleteDownloadObjects(_ downloadSession: DownloadSession) @MainActor func downloadSessionDidCompleteDownloadObjects(_ downloadSession: DownloadSession)
} }
@objc public final class DownloadSession: NSObject { @MainActor @objc public final class DownloadSession: NSObject {
private var urlSession: URLSession! private var urlSession: URLSession!
private var tasksInProgress = Set<URLSessionTask>() private var tasksInProgress = Set<URLSessionTask>()
@ -70,7 +70,7 @@ public protocol DownloadSessionDelegate {
} }
} }
public func downloadObjects(_ objects: NSSet) { @MainActor public func downloadObjects(_ objects: NSSet) {
for oneObject in objects { for oneObject in objects {
if !representedObjects.contains(oneObject) { if !representedObjects.contains(oneObject) {
representedObjects.add(oneObject) representedObjects.add(oneObject)
@ -175,7 +175,7 @@ extension DownloadSession: URLSessionDataDelegate {
private extension DownloadSession { private extension DownloadSession {
func addDataTask(_ representedObject: AnyObject) { @MainActor func addDataTask(_ representedObject: AnyObject) {
guard tasksPending.count < 500 else { guard tasksPending.count < 500 else {
queue.insert(representedObject, at: 0) queue.insert(representedObject, at: 0)
return return
@ -213,7 +213,7 @@ private extension DownloadSession {
return taskIdentifierToInfoDictionary[task.taskIdentifier] return taskIdentifierToInfoDictionary[task.taskIdentifier]
} }
func removeTask(_ task: URLSessionTask) { @MainActor func removeTask(_ task: URLSessionTask) {
tasksInProgress.remove(task) tasksInProgress.remove(task)
tasksPending.remove(task) tasksPending.remove(task)
taskIdentifierToInfoDictionary[task.taskIdentifier] = nil taskIdentifierToInfoDictionary[task.taskIdentifier] = nil