Lock and unlock when accessing sync actions in FileProviderExt to protect against possible races

Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
This commit is contained in:
Claudio Cambra 2024-07-16 19:35:09 +08:00
parent 939d67bfcc
commit 92f42bc16d
No known key found for this signature in database
GPG key ID: C839200C384636B0
2 changed files with 15 additions and 1 deletions

View file

@ -134,7 +134,12 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
}
func updatedSyncStateReporting(oldActions: Set<UUID>) {
guard oldActions.isEmpty != syncActions.isEmpty else { return }
actionsLock.lock()
guard oldActions.isEmpty != syncActions.isEmpty else {
actionsLock.unlock()
return
}
let command = "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE"
var argument: String?
@ -144,6 +149,8 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
argument = errorActions.isEmpty ? "SYNC_FINISHED" : "SYNC_FAILED"
errorActions = []
}
actionsLock.unlock()
guard let argument else { return }
Logger.fileProviderExtension.debug("Reporting sync \(argument)")

View file

@ -39,6 +39,7 @@ import OSLog
var syncActions = Set<UUID>()
var errorActions = Set<UUID>()
var actionsLock = NSLock()
// Whether or not we are going to recursively scan new folders when they are discovered.
// Apple's recommendation is that we should always scan the file hierarchy fully.
@ -71,22 +72,28 @@ import OSLog
}
func insertSyncAction(_ actionId: UUID) {
actionsLock.lock()
let oldActions = syncActions
syncActions.insert(actionId)
actionsLock.unlock()
updatedSyncStateReporting(oldActions: oldActions)
}
func insertErrorAction(_ actionId: UUID) {
actionsLock.lock()
let oldActions = syncActions
syncActions.remove(actionId)
errorActions.insert(actionId)
actionsLock.unlock()
updatedSyncStateReporting(oldActions: oldActions)
}
func removeSyncAction(_ actionId: UUID) {
actionsLock.lock()
let oldActions = syncActions
syncActions.remove(actionId)
errorActions.remove(actionId)
actionsLock.unlock()
updatedSyncStateReporting(oldActions: oldActions)
}