From 118a9e32587f650da068f9060ea25a4a8606f37a Mon Sep 17 00:00:00 2001 From: alex-z Date: Sat, 17 Feb 2024 14:55:38 +0100 Subject: [PATCH] Fix crash when deleting a local sync folder during sync. Signed-off-by: alex-z --- src/gui/folder.cpp | 45 ++++++++++++++++++++++++++++++++------------- src/gui/folder.h | 5 +++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index ace5524cb3d91..163392513d456 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -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())) { @@ -971,6 +973,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 @@ -1588,6 +1592,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(); diff --git a/src/gui/folder.h b/src/gui/folder.h index 3398216dfa922..ec50403afe558 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -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. */