Fix thread-safety crash in ProfileUpdateTask
Snapshot @Published properties before async suspension points to prevent SIGBUS from corrupted pointers due to concurrent access.
This commit is contained in:
@@ -52,14 +52,15 @@ public enum ProfileUpdateTask {
|
|||||||
static func updateProfiles(_ profiles: [Profile]) async -> Bool {
|
static func updateProfiles(_ profiles: [Profile]) async -> Bool {
|
||||||
var success = true
|
var success = true
|
||||||
for profile in profiles {
|
for profile in profiles {
|
||||||
|
let profileName = profile.name
|
||||||
if profile.lastUpdated! > Date(timeIntervalSinceNow: -profile.autoUpdateIntervalOrDefault) {
|
if profile.lastUpdated! > Date(timeIntervalSinceNow: -profile.autoUpdateIntervalOrDefault) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try await profile.updateRemoteProfile()
|
try await profile.updateRemoteProfile()
|
||||||
NSLog("Updated profile \(profile.name)")
|
NSLog("Updated profile %@", profileName)
|
||||||
} catch {
|
} catch {
|
||||||
NSLog("Update profile \(profile.name) failed: \(error.localizedDescription)")
|
NSLog("Update profile %@ failed: %@", profileName, error.localizedDescription)
|
||||||
success = false
|
success = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ public extension Profile {
|
|||||||
if type != .remote {
|
if type != .remote {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let remoteContent = try await HTTPClient.getStringAsync(remoteURL)
|
let url = remoteURL
|
||||||
|
let remoteContent = try await HTTPClient.getStringAsync(url)
|
||||||
try await BlockingIO.run {
|
try await BlockingIO.run {
|
||||||
var error: NSError?
|
var error: NSError?
|
||||||
LibboxCheckConfig(remoteContent, &error)
|
LibboxCheckConfig(remoteContent, &error)
|
||||||
@@ -15,7 +16,9 @@ public extension Profile {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastUpdated = Date()
|
await MainActor.run {
|
||||||
|
lastUpdated = Date()
|
||||||
|
}
|
||||||
try await ProfileManager.update(self)
|
try await ProfileManager.update(self)
|
||||||
do {
|
do {
|
||||||
let oldContent = try await readAsync()
|
let oldContent = try await readAsync()
|
||||||
|
|||||||
Reference in New Issue
Block a user