Fix crash when deleting a local sync folder during sync.
authoralex-z <blackslayer4@gmail.com>
Sat, 17 Feb 2024 13:55:38 +0000 (14:55 +0100)
committerallexzander <allexzander@users.noreply.github.com>
Fri, 23 Feb 2024 11:46:17 +0000 (12:46 +0100)
Signed-off-by: alex-z <blackslayer4@gmail.com>
src/gui/folder.cpp
src/gui/folder.h

index afa90485e99a44cee79ee627e8b15d4cae6e652b..a8098fd9a6a0b0bcdac1e249d5b025340b2d1bfb 100644 (file)
@@ -561,19 +561,21 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
 
     auto relativePath = path.midRef(this->path().size());
 
-    if (pathIsIgnored(path)) {
-        const auto pinState = _vfs->pinState(relativePath.toString());
-        if (!pinState || *pinState != PinState::Excluded) {
-            if (!_vfs->setPinState(relativePath.toString(), PinState::Excluded)) {
-                qCWarning(lcFolder) << "Could not set pin state of" << relativePath << "to excluded";
+    if (_vfs) {
+        if (pathIsIgnored(path)) {
+            const auto pinState = _vfs->pinState(relativePath.toString());
+            if (!pinState || *pinState != PinState::Excluded) {
+                if (!_vfs->setPinState(relativePath.toString(), PinState::Excluded)) {
+                    qCWarning(lcFolder) << "Could not set pin state of" << relativePath << "to excluded";
+                }
             }
-        }
-        return;
-    } else {
-        const auto pinState = _vfs->pinState(relativePath.toString());
-        if (pinState && *pinState == PinState::Excluded) {
-            if (!_vfs->setPinState(relativePath.toString(), PinState::Inherited)) {
-                qCWarning(lcFolder) << "Could not switch pin state of" << relativePath << "from" << *pinState << "to inherited";
+            return;
+        } else {
+            const auto pinState = _vfs->pinState(relativePath.toString());
+            if (pinState && *pinState == PinState::Excluded) {
+                if (!_vfs->setPinState(relativePath.toString(), PinState::Inherited)) {
+                    qCWarning(lcFolder) << "Could not switch pin state of" << relativePath << "from" << *pinState << "to inherited";
+                }
             }
         }
     }
@@ -610,7 +612,7 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
         // an attribute change (pin state) that caused the notification
         bool spurious = false;
         if (record.isValid()
-            && !FileSystem::fileChanged(path, record._fileSize, record._modtime)) {
+            && !FileSystem::fileChanged(path, record._fileSize, record._modtime) && _vfs) {
             spurious = true;
 
             if (auto pinState = _vfs->pinState(relativePath.toString())) {
@@ -974,6 +976,8 @@ void Folder::wipeForRemoval()
     // Delete files that have been partially downloaded.
     slotDiscardDownloadProgress();
 
+    disconnectFolderWatcher();
+
     // Unregister the socket API so it does not keep the .sync_journal file open
     FolderMan::instance()->socketApi()->slotUnregisterPath(alias());
     _journal.close(); // close the sync journal
@@ -1591,6 +1595,21 @@ void Folder::registerFolderWatcher()
     _folderWatcher->startNotificatonTest(path() + QLatin1String(".nextcloudsync.log"));
 }
 
+void Folder::disconnectFolderWatcher()
+{
+    if (!_folderWatcher) {
+        return;
+    }
+    disconnect(_folderWatcher.data(), &FolderWatcher::pathChanged, nullptr, nullptr);
+    disconnect(_folderWatcher.data(), &FolderWatcher::lostChanges, this, &Folder::slotNextSyncFullLocalDiscovery);
+    disconnect(_folderWatcher.data(), &FolderWatcher::becameUnreliable, this, &Folder::slotWatcherUnreliable);
+    if (_accountState->account()->capabilities().filesLockAvailable()) {
+        disconnect(_folderWatcher.data(), &FolderWatcher::filesLockReleased, this, &Folder::slotFilesLockReleased);
+        disconnect(_folderWatcher.data(), &FolderWatcher::lockedFilesFound, this, &Folder::slotLockedFilesFound);
+    }
+    disconnect(_folderWatcher.data(), &FolderWatcher::filesLockImposed, this, &Folder::slotFilesLockImposed);
+}
+
 bool Folder::virtualFilesEnabled() const
 {
     return _definition.virtualFilesMode != Vfs::Off && !isVfsOnOffSwitchPending();
index 3398216dfa922ad7fcebcae2c8eef13e8d00096e..ec50403afe55812a18fd07426f55e93d92dd7721 100644 (file)
@@ -400,6 +400,11 @@ public slots:
 private slots:
     void slotSyncStarted();
     void slotSyncFinished(bool);
+    /*
+     * Disconnects all the slots from the FolderWatcher
+     * Needs to be called each time a folder is removed
+     */
+    void disconnectFolderWatcher();
 
     /** Adds a error message that's not tied to a specific item.
      */