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>) { 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" let command = "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE"
var argument: String? var argument: String?
@ -144,6 +149,8 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
argument = errorActions.isEmpty ? "SYNC_FINISHED" : "SYNC_FAILED" argument = errorActions.isEmpty ? "SYNC_FINISHED" : "SYNC_FAILED"
errorActions = [] errorActions = []
} }
actionsLock.unlock()
guard let argument else { return } guard let argument else { return }
Logger.fileProviderExtension.debug("Reporting sync \(argument)") Logger.fileProviderExtension.debug("Reporting sync \(argument)")

View file

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