Skip to content

Commit

Permalink
Avoid potential race condition by making Storage thread safe (#26)
Browse files Browse the repository at this point in the history
* fix:avoid race condition by making Storage thread safe

* Update Storage.swift

Use accessQueue only when it's necessary

* Use legacy guard syntax for compatibility with older swift version's

* Remove extra space
  • Loading branch information
mjbashtani authored Jan 17, 2023
1 parent e850e9f commit b2da539
Showing 1 changed file with 28 additions and 18 deletions.
46 changes: 28 additions & 18 deletions Sources/NetShears/Storage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,50 @@
import Foundation

final class Storage: NSObject {

static let shared: Storage = Storage()

private let accessQueue = DispatchQueue(label: "com.netshears.queue", attributes: .concurrent)

private(set) var requests: [NetShearsRequestModel] = []

var filteredRequests: [NetShearsRequestModel] {
return getFilteredRequests()
getFilteredRequests()
}

func saveRequest(request: NetShearsRequestModel?){
guard request != nil else {
return
func saveRequest(request: NetShearsRequestModel) {
accessQueue.async(flags: .barrier) { [weak self] in
guard let self = self else {
return
}
if let index = self.requests.firstIndex(where: { (req) -> Bool in
return request.id == req.id ? true : false
}) {
self.requests[index] = request
} else {
self.requests.insert(request, at: 0)
}
NotificationCenter.default.post(name: NSNotification.Name.NewRequestNotification, object: nil)
}

if let index = requests.firstIndex(where: { (req) -> Bool in
return request?.id == req.id ? true : false
}) {
requests[index] = request!
} else {
requests.insert(request!, at: 0)
}
NotificationCenter.default.post(name: NSNotification.Name.NewRequestNotification, object: nil)
}

func clearRequests() {
requests.removeAll()
accessQueue.async(flags: .barrier) { [weak self] in
self?.requests.removeAll()
}
}

private func getFilteredRequests() -> [NetShearsRequestModel] {
var localRequests = [NetShearsRequestModel]()
accessQueue.sync {
localRequests = requests
}
return Self.filterRequestsIfNeeded(localRequests)
}

private static func filterRequestsIfNeeded(_ requests: [NetShearsRequestModel]) -> [NetShearsRequestModel] {
guard case Ignore.enabled(let ignoreHandler) = NetShears.shared.ignore else {
return requests
}
let filteredRequests = requests.filter { ignoreHandler($0) == false }
return filteredRequests
return requests.filter { ignoreHandler($0) == false }
}

}

0 comments on commit b2da539

Please sign in to comment.