From 01ada2ff6e8ad931e3a81bc48c8cb48f3259ebb3 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Fri, 8 Mar 2024 16:54:45 +0100 Subject: [PATCH] fix: fixed data race in the Disk module (#1823) --- Modules/Disk/main.swift | 60 ++++++++++++++-------------------------- Modules/Disk/popup.swift | 6 ++-- 2 files changed, 23 insertions(+), 43 deletions(-) diff --git a/Modules/Disk/main.swift b/Modules/Disk/main.swift index 36c27f13..02917fa3 100644 --- a/Modules/Disk/main.swift +++ b/Modules/Disk/main.swift @@ -58,7 +58,11 @@ public struct drive: Codable { public class Disks: Codable { private var queue: DispatchQueue = DispatchQueue(label: "eu.exelban.Stats.Disk.SynchronizedArray") - private var array: [drive] = [] + private var _array: [drive] = [] + public var array: [drive] { + get { self.queue.sync { self._array } } + set { self.queue.sync { self._array = newValue } } + } enum CodingKeys: String, CodingKey { case array @@ -89,82 +93,58 @@ public class Disks: Codable { // swiftlint:enable empty_count public func first(where predicate: (drive) -> Bool) -> drive? { - var result: drive? - self.queue.sync { result = self.array.first(where: predicate) } - return result + return self.array.first(where: predicate) } public func index(where predicate: (drive) -> Bool) -> Int? { - var result: Int? - self.queue.sync { result = self.array.firstIndex(where: predicate) } - return result + return self.array.firstIndex(where: predicate) } public func map(_ transform: (drive) -> ElementOfResult?) -> [ElementOfResult] { - var result = [ElementOfResult]() - self.queue.sync { result = self.array.compactMap(transform) } - return result + return self.array.compactMap(transform) } public func reversed() -> [drive] { - var result: [drive] = [] - self.queue.sync(flags: .barrier) { result = self.array.reversed() } - return result + return self.array.reversed() } func forEach(_ body: (drive) -> Void) { - self.queue.sync { self.array.forEach(body) } + self.array.forEach(body) } public func append( _ element: drive) { - self.queue.async(flags: .barrier) { - if !self.array.contains(where: {$0.BSDName == element.BSDName}) { - self.array.append(element) - } + if !self.array.contains(where: {$0.BSDName == element.BSDName}) { + self.array.append(element) } } public func remove(at index: Int) { - self.queue.async(flags: .barrier) { - self.array.remove(at: index) - } + self.array.remove(at: index) } public func sort() { - self.queue.async(flags: .barrier) { - self.array.sort{ $1.removable } - } + self.array.sort{ $1.removable } } func updateFreeSize(_ idx: Int, newValue: Int64) { - self.queue.async(flags: .barrier) { - self.array[idx].free = newValue - } + self.array[idx].free = newValue } func updateReadWrite(_ idx: Int, read: Int64, write: Int64) { - self.queue.async(flags: .barrier) { - self.array[idx].activity.readBytes = read - self.array[idx].activity.writeBytes = write - } + self.array[idx].activity.readBytes = read + self.array[idx].activity.writeBytes = write } func updateRead(_ idx: Int, newValue: Int64) { - self.queue.async(flags: .barrier) { - self.array[idx].activity.read = newValue - } + self.array[idx].activity.read = newValue } func updateWrite(_ idx: Int, newValue: Int64) { - self.queue.async(flags: .barrier) { - self.array[idx].activity.write = newValue - } + self.array[idx].activity.write = newValue } func updateSMARTData(_ idx: Int, smart: smart_t?) { - self.queue.async(flags: .barrier) { - self.array[idx].smart = smart - } + self.array[idx].smart = smart } } diff --git a/Modules/Disk/popup.swift b/Modules/Disk/popup.swift index af6dec54..61c1581c 100644 --- a/Modules/Disk/popup.swift +++ b/Modules/Disk/popup.swift @@ -89,6 +89,8 @@ internal class Popup: PopupWrapper { return view } + // MARK: - callbacks + internal func capacityCallback(_ value: Disks) { defer { let h = self.disks.subviews.map({ $0.bounds.height + self.disks.spacing }).reduce(0, +) - self.disks.spacing @@ -109,7 +111,7 @@ internal class Popup: PopupWrapper { view.update(free: drive.free, smart: drive.smart) } else { self.disks.addArrangedSubview(DiskView( - width: self.frame.width, + width: Constants.Popup.width, BSDName: drive.BSDName, name: drive.mediaName, size: drive.size, @@ -130,8 +132,6 @@ internal class Popup: PopupWrapper { } } - // MARK: - callbacks - internal func processCallback(_ list: [Disk_process]) { DispatchQueue.main.async(execute: { if !(self.window?.isVisible ?? false) && self.processesInitialized {