fix: fixed race condition crashes in Chart and Stack widgets (#2944)

Ensure data mutations from background readers are dispatched to the main thread to prevent conflicts with drawing logic (which runs on main thread). This resolves SIGTRAP and SIGABRT crashes observed during extended runtime.
This commit is contained in:
Andy Chong
2026-02-02 00:39:00 +08:00
committed by GitHub
parent 9f7b5303e0
commit a69627f135
4 changed files with 43 additions and 37 deletions

View File

@@ -223,6 +223,7 @@ public class BarChart: WidgetWrapper {
}
public func setValue(_ newValue: [[ColorValue]]) {
DispatchQueue.main.async(execute: {
let tolerance: CGFloat = 0.01
let isDifferent = self._value.count != newValue.count || zip(self._value, newValue).contains { row1, row2 in
row1.count != row2.count || zip(row1, row2).contains { val1, val2 in
@@ -232,18 +233,23 @@ public class BarChart: WidgetWrapper {
guard isDifferent else { return }
self._value = newValue
self.redraw()
})
}
public func setPressure(_ newPressureLevel: RAMPressure) {
DispatchQueue.main.async(execute: {
guard self._pressureLevel != newPressureLevel else { return }
self._pressureLevel = newPressureLevel
self.redraw()
})
}
public func setColorZones(_ newColorZones: colorZones) {
DispatchQueue.main.async(execute: {
guard self._colorZones != newColorZones else { return }
self._colorZones = newColorZones
self.redraw()
})
}
// MARK: - Settings

View File

@@ -249,17 +249,17 @@ public class LineChart: WidgetWrapper {
}
public func setValue(_ newValue: Double) {
self._value = newValue
DispatchQueue.main.async(execute: {
self._value = newValue
self.chart.addValue(newValue)
self.display()
})
}
public func setPressure(_ newPressureLevel: RAMPressure) {
DispatchQueue.main.async(execute: {
guard self._pressureLevel != newPressureLevel else { return }
self._pressureLevel = newPressureLevel
DispatchQueue.main.async(execute: {
self.display()
})
}

View File

@@ -263,10 +263,10 @@ public class NetworkChart: WidgetWrapper {
}
public func setValue(upload: Double, download: Double) {
DispatchQueue.main.async(execute: {
self.points.remove(at: 0)
self.points.append((upload, download))
DispatchQueue.main.async(execute: {
if self.window?.isVisible ?? false {
self.display()
}

View File

@@ -226,6 +226,7 @@ public class StackWidget: WidgetWrapper {
}
public func setValues(_ values: [Stack_t]) {
DispatchQueue.main.async(execute: {
var tableNeedsToBeUpdated: Bool = false
values.forEach { (p: Stack_t) in
@@ -243,7 +244,6 @@ public class StackWidget: WidgetWrapper {
}
self.values = diff.sorted(by: { $0.index < $1.index })
DispatchQueue.main.async(execute: {
if tableNeedsToBeUpdated {
self.orderTableView.update()
}