Browse Source

Improvements FileProvider : add trade-safe for fileProviderSignal dictionary

Marino Faggiana 6 years ago
parent
commit
800cf7d7b8

+ 14 - 10
PickerFileProvider/FileProviderData.swift

@@ -39,8 +39,10 @@ class FileProviderData: NSObject {
         
     func setupActiveAccount() -> Bool {
         
-        groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
-        fileProviderStorageURL = groupURL!.appendingPathComponent(k_assetLocalIdentifierFileProviderStorage)
+        queueTradeSafe.sync(flags: .barrier) {
+            groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
+            fileProviderStorageURL = groupURL!.appendingPathComponent(k_assetLocalIdentifierFileProviderStorage)
+        }
         
         // Create dir File Provider Storage
         do {
@@ -57,14 +59,16 @@ class FileProviderData: NSObject {
             assert(false, "change user")
         }
         
-        account = activeAccount.account
-        accountUser = activeAccount.user
-        accountUserID = activeAccount.userID
-        accountPassword = activeAccount.password
-        accountUrl = activeAccount.url
-        homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(activeAccount.url)
-        directoryUser = CCUtility.getDirectoryActiveUser(activeAccount.user, activeUrl: activeAccount.url)
-                
+        queueTradeSafe.sync(flags: .barrier) {
+            account = activeAccount.account
+            accountUser = activeAccount.user
+            accountUserID = activeAccount.userID
+            accountPassword = activeAccount.password
+            accountUrl = activeAccount.url
+            homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(activeAccount.url)
+            directoryUser = CCUtility.getDirectoryActiveUser(activeAccount.user, activeUrl: activeAccount.url)
+        }
+        
         return true
     }
     

+ 41 - 39
PickerFileProvider/FileProviderEnumerator.swift

@@ -180,53 +180,55 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         
         guard #available(iOS 11, *) else { return }
     
-        // Report the deleted items
-        //
         var itemsDelete = [NSFileProviderItemIdentifier]()
-        
-        if enumeratedItemIdentifier == .workingSet {
-            for (itemIdentifier, _) in fileProviderSignalDeleteWorkingSetItemIdentifier {
-                itemsDelete.append(itemIdentifier)
-            }
-            fileProviderSignalDeleteWorkingSetItemIdentifier.removeAll()
-        } else {
-            for (itemIdentifier, _) in fileProviderSignalDeleteContainerItemIdentifier {
-                itemsDelete.append(itemIdentifier)
-            }
-            fileProviderSignalDeleteContainerItemIdentifier.removeAll()
-        }
-        
-        // Report the updated items
-        //
         var itemsUpdate = [FileProviderItem]()
-        
-        if enumeratedItemIdentifier == .workingSet {
-            for (itemIdentifier, item) in fileProviderSignalUpdateWorkingSetItem {
-                let account = providerData.getAccountFromItemIdentifier(itemIdentifier)
-                if account != nil && account == providerData.account {
-                    itemsUpdate.append(item)
-                } else {
+
+        queueTradeSafe.sync(flags: .barrier) {
+
+            // Report the deleted items
+            //
+            if enumeratedItemIdentifier == .workingSet {
+                for (itemIdentifier, _) in fileProviderSignalDeleteWorkingSetItemIdentifier {
                     itemsDelete.append(itemIdentifier)
                 }
-            }
-            fileProviderSignalUpdateWorkingSetItem.removeAll()
-        } else {
-            for (itemIdentifier, item) in fileProviderSignalUpdateContainerItem {
-                let account = providerData.getAccountFromItemIdentifier(itemIdentifier)
-                if account != nil && account == providerData.account {
-                    itemsUpdate.append(item)
-                } else {
+                fileProviderSignalDeleteWorkingSetItemIdentifier.removeAll()
+            } else {
+                for (itemIdentifier, _) in fileProviderSignalDeleteContainerItemIdentifier {
                     itemsDelete.append(itemIdentifier)
                 }
+                fileProviderSignalDeleteContainerItemIdentifier.removeAll()
             }
-            fileProviderSignalUpdateContainerItem.removeAll()
+            
+            // Report the updated items
+            //
+            if enumeratedItemIdentifier == .workingSet {
+                for (itemIdentifier, item) in fileProviderSignalUpdateWorkingSetItem {
+                    let account = providerData.getAccountFromItemIdentifier(itemIdentifier)
+                    if account != nil && account == providerData.account {
+                        itemsUpdate.append(item)
+                    } else {
+                        itemsDelete.append(itemIdentifier)
+                    }
+                }
+                fileProviderSignalUpdateWorkingSetItem.removeAll()
+            } else {
+                for (itemIdentifier, item) in fileProviderSignalUpdateContainerItem {
+                    let account = providerData.getAccountFromItemIdentifier(itemIdentifier)
+                    if account != nil && account == providerData.account {
+                        itemsUpdate.append(item)
+                    } else {
+                        itemsDelete.append(itemIdentifier)
+                    }
+                }
+                fileProviderSignalUpdateContainerItem.removeAll()
+            }
+            
+            observer.didDeleteItems(withIdentifiers: itemsDelete)
+            observer.didUpdate(itemsUpdate)
+            
+            let data = "\(currentAnchor)".data(using: .utf8)
+            observer.finishEnumeratingChanges(upTo: NSFileProviderSyncAnchor(data!), moreComing: false)
         }
-        
-        observer.didDeleteItems(withIdentifiers: itemsDelete)
-        observer.didUpdate(itemsUpdate)
-        
-        let data = "\(currentAnchor)".data(using: .utf8)
-        observer.finishEnumeratingChanges(upTo: NSFileProviderSyncAnchor(data!), moreComing: false)        
     }
     
     func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {

+ 43 - 37
PickerFileProvider/FileProviderExtension+Actions.swift

@@ -73,10 +73,11 @@ extension FileProviderExtension {
                 
                 let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier!, providerData: self.providerData)
                 
-                fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-                self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                queueTradeSafe.sync(flags: .barrier) {
+                    fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+                    fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+                    self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                }
                 
                 completionHandler(item, nil)
                 
@@ -113,10 +114,11 @@ extension FileProviderExtension {
         deleteFile(withIdentifier: itemIdentifier, parentItemIdentifier: parentItemIdentifier, metadata: metadata)
 
         // return immediately
-        fileProviderSignalDeleteContainerItemIdentifier[itemIdentifier] = itemIdentifier
-        fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier
-
-        self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+        queueTradeSafe.sync(flags: .barrier) {
+            fileProviderSignalDeleteContainerItemIdentifier[itemIdentifier] = itemIdentifier
+            fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier
+            self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+        }
         
         completionHandler(nil)
     }
@@ -179,11 +181,12 @@ extension FileProviderExtension {
             
             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: self.providerData)
             
-            fileProviderSignalUpdateContainerItem[itemIdentifier] = item
-            fileProviderSignalUpdateWorkingSetItem[itemIdentifier] = item
-
-            self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
-                
+            queueTradeSafe.sync(flags: .barrier) {
+                fileProviderSignalUpdateContainerItem[itemIdentifier] = item
+                fileProviderSignalUpdateWorkingSetItem[itemIdentifier] = item
+                self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+            }
+            
             completionHandler(item, nil)
             
         }, failure: { (errorMessage, errorCode) in
@@ -249,12 +252,13 @@ extension FileProviderExtension {
             }
             
             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: self.providerData)
-                
-            fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-            self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
-                
+            
+            queueTradeSafe.sync(flags: .barrier) {
+                fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+                self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+            }
+            
             completionHandler(item, nil)
             
         }, failure: { (errorMessage, errorCode) in
@@ -296,11 +300,12 @@ extension FileProviderExtension {
         
         let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
         
-        fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-        fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-        signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
-
+        queueTradeSafe.sync(flags: .barrier) {
+            fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+        }
+        
         completionHandler(item, nil)
         
         if (favorite == true && metadata.favorite == false) || (favorite == false && metadata.favorite == true) {
@@ -328,11 +333,12 @@ extension FileProviderExtension {
         
         let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
         
-        fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-        fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-        signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
-
+        queueTradeSafe.sync(flags: .barrier) {
+            fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+        }
+        
         completionHandler(item, nil)
     }
     
@@ -447,21 +453,21 @@ extension FileProviderExtension {
         }
             
         let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier, providerData: self.providerData)
-            
-        fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-        fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-        self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
-            
+        
+        queueTradeSafe.sync(flags: .barrier) {
+            fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+        }
+        
         completionHandler(item, nil)
     }
     
     func createFileName(_ fileName: String, directoryID: String, serverUrl: String) -> String {
         
-        let serialQueue = DispatchQueue(label: "queueCreateFileName")
         var resultFileName = fileName
         
-        serialQueue.sync {
+        queueTradeSafe.sync {
             
             var exitLoop = false
             

+ 21 - 17
PickerFileProvider/FileProviderExtension+Network.swift

@@ -69,10 +69,11 @@ extension FileProviderExtension {
         }, failure: { (errorMessage, errorCode) in
             
             // remove itemIdentifier on fileProviderSignalDeleteItemIdentifier
-            fileProviderSignalDeleteContainerItemIdentifier.removeValue(forKey: itemIdentifier)
-            fileProviderSignalDeleteWorkingSetItemIdentifier.removeValue(forKey: itemIdentifier)
-
-            self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+            queueTradeSafe.async(flags: .barrier) {
+                fileProviderSignalDeleteContainerItemIdentifier.removeValue(forKey: itemIdentifier)
+                fileProviderSignalDeleteWorkingSetItemIdentifier.removeValue(forKey: itemIdentifier)
+                self.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+            }
         })
     }
     
@@ -105,10 +106,11 @@ extension FileProviderExtension {
 
             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: self.providerData)
             
-            fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-            self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+            queueTradeSafe.async(flags: .barrier) {
+                fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+                self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+            }
             
         })
     }
@@ -129,10 +131,11 @@ extension FileProviderExtension {
                 
                 let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
             
-                fileProviderSignalDeleteContainerItemIdentifier[item.itemIdentifier] = item.itemIdentifier
-                fileProviderSignalDeleteWorkingSetItemIdentifier[item.itemIdentifier] = item.itemIdentifier
-
-                signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                queueTradeSafe.async(flags: .barrier) {
+                    fileProviderSignalDeleteContainerItemIdentifier[item.itemIdentifier] = item.itemIdentifier
+                    fileProviderSignalDeleteWorkingSetItemIdentifier[item.itemIdentifier] = item.itemIdentifier
+                    self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                }
             }
         }
         
@@ -157,11 +160,12 @@ extension FileProviderExtension {
                 }
                 
                 let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
-                    
-                fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
-                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-
-                signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                
+                queueTradeSafe.async(flags: .barrier) {
+                    fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+                    fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+                    self.signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+                }
             }
             
             uploadFile()

+ 15 - 16
PickerFileProvider/FileProviderExtension.swift

@@ -35,6 +35,9 @@ var fileProviderSignalUpdateWorkingSetItem = [NSFileProviderItemIdentifier:FileP
 // Rank favorite
 var listFavoriteIdentifierRank = [String:NSNumber]()
 
+// Queue for trade-safe
+let queueTradeSafe = DispatchQueue(label: "com.nextcloud.fileproviderextension.tradesafe", attributes: .concurrent)
+
 var currentAnchor: UInt64 = 0
 
 /* -----------------------------------------------------------------------------------------------------------------------------------------------
@@ -114,11 +117,6 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { throw NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo:[:]) }
         
         var maybeEnumerator: NSFileProviderEnumerator? = nil
-        
-        // update workingset
-        if (containerItemIdentifier != NSFileProviderItemIdentifier.workingSet) {
-            self.updateWorkingSet()
-        }
 
         if (containerItemIdentifier == NSFileProviderItemIdentifier.rootContainer) {
             
@@ -127,6 +125,9 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
                 throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
             }
             
+            // Update WorkingSet
+            self.updateWorkingSet()
+            
             maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
         } else if (containerItemIdentifier == NSFileProviderItemIdentifier.workingSet) {
             maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
@@ -176,12 +177,10 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
         /* ONLY iOS 11*/
         guard #available(iOS 11, *) else { return }
         
-        var updateItemsWorkingSet = [NSFileProviderItemIdentifier:FileProviderItem]()
-        
         // ***** Favorite Files <-> Favorite Nextcloud *****
         
         listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank()
-
+        
         // (ADD)
         for (identifier, _) in listFavoriteIdentifierRank {
             
@@ -194,8 +193,10 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
             }
             
             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
-        
-            updateItemsWorkingSet[item.itemIdentifier] = item
+            
+            queueTradeSafe.sync(flags: .barrier) {
+                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            }
         }
         
         // (REMOVE)
@@ -210,15 +211,14 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
                 listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue)
                 let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
                 
-                updateItemsWorkingSet[item.itemIdentifier] = item
+                queueTradeSafe.sync(flags: .barrier) {
+                    fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+                }
             }
         }
         
         // Update workingSet
-        for (itemIdentifier, item) in updateItemsWorkingSet {
-            fileProviderSignalUpdateWorkingSetItem[itemIdentifier] = item
-            self.signalEnumerator(for: [.workingSet])
-        }
+        self.signalEnumerator(for: [.workingSet])
     }
     
     // MARK: - Item
@@ -257,7 +257,6 @@ class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
             
             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier, providerData: providerData)
             return item
-
         }
         
         throw NSFileProviderError(.noSuchItem)

+ 2 - 2
iOSClient/Brand/Picker.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.21.0</string>
+	<string>2.21.1</string>
 	<key>CFBundleVersion</key>
-	<string>00018</string>
+	<string>00001</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/PickerFileProvider.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.21.0</string>
+	<string>2.21.1</string>
 	<key>CFBundleVersion</key>
-	<string>00018</string>
+	<string>00001</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionFileProviderDocumentGroup</key>

+ 2 - 2
iOSClient/Brand/Share.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.21.0</string>
+	<string>2.21.1</string>
 	<key>CFBundleVersion</key>
-	<string>00018</string>
+	<string>00001</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/iOSClient.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.21.0</string>
+	<string>2.21.1</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>
@@ -69,7 +69,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>00018</string>
+	<string>00001</string>
 	<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
 	<true/>
 	<key>Fabric</key>