From 594d8c942e9ea31f7949e87202b7abe4342c68bd Mon Sep 17 00:00:00 2001 From: liyigang Date: Thu, 31 Aug 2023 11:11:14 +0800 Subject: [PATCH] fix: [workspace]F5 shortcut held down, dde-file-manager crashes F5 forced refresh, filesortworker thread destructed filedataitem, causing main thread to crash Log: F5 shortcut held down, dde-file-manager crashes Bug: https://pms.uniontech.com/bug-view-217305.html --- .../dfmplugin-workspace/models/fileitemdata.h | 2 + .../models/fileviewmodel.cpp | 12 +++--- .../utils/filesortworker.cpp | 42 ++++++++++--------- .../utils/filesortworker.h | 17 ++++---- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.h b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.h index ae13d72dc6..3dfcc9e5e5 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileitemdata.h @@ -41,4 +41,6 @@ class FileItemData } +typedef QSharedPointer FileItemDataPointer; + #endif // FILEITEMDATA_H diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp index 6bad260eeb..06835f2e48 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/models/fileviewmodel.cpp @@ -76,14 +76,14 @@ QModelIndex FileViewModel::index(int row, int column, const QModelIndex &parent) if (!filterSortWorker) return QModelIndex(); - FileItemData *itemData = nullptr; + FileItemDataPointer itemData = nullptr; if (!isParentValid) { itemData = filterSortWorker->rootData(); } else { itemData = filterSortWorker->childData(row); } - return createIndex(row, column, itemData); + return createIndex(row, column, itemData.data()); } QUrl FileViewModel::rootUrl() const @@ -98,7 +98,7 @@ QModelIndex FileViewModel::rootIndex() const auto data = filterSortWorker->rootData(); if (data) { - return createIndex(0, 0, data); + return createIndex(0, 0, data.data()); } else { return QModelIndex(); } @@ -158,7 +158,7 @@ FileInfoPointer FileViewModel::fileInfo(const QModelIndex &index) const return nullptr; const QModelIndex &parentIndex = index.parent(); - FileItemData *item = nullptr; + FileItemDataPointer item{ nullptr }; if (!parentIndex.isValid()) { item = filterSortWorker->rootData(); } else { @@ -272,7 +272,7 @@ QVariant FileViewModel::data(const QModelIndex &index, int role) const if (filterSortWorker.isNull()) return QVariant(); - FileItemData *itemData = nullptr; + FileItemDataPointer itemData = nullptr; int columnRole = role; if (!parentIndex.isValid()) { itemData = filterSortWorker->rootData(); @@ -783,7 +783,7 @@ void FileViewModel::initFilterSortWork() filterSortWorker.reset(new FileSortWorker(dirRootUrl, currentKey, filterCallback, nameFilters, currentFilters)); beginInsertRows(QModelIndex(), 0, 0); - filterSortWorker->setRootData(new FileItemData(dirRootUrl, InfoFactory::create(dirRootUrl))); + filterSortWorker->setRootData(FileItemDataPointer(new FileItemData(dirRootUrl, InfoFactory::create(dirRootUrl)))); endInsertRows(); filterSortWorker->setSortAgruments(order, role, Application::instance()->appAttribute(Application::kFileAndDirMixedSort).toBool()); filterSortWorker->moveToThread(filterSortThread.data()); diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp index aed105f6b9..51e7bd1ad3 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.cpp @@ -3,7 +3,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "filesortworker.h" -#include "models/fileitemdata.h" #include #include #include @@ -31,11 +30,6 @@ FileSortWorker::FileSortWorker(const QUrl &url, const QString &key, FileViewFilt FileSortWorker::~FileSortWorker() { isCanceled = true; - if (rootdata) { - rootdata = nullptr; - delete rootdata; - } - qDeleteAll(childrenDataMap.values()); childrenDataMap.clear(); childrenUrlList.clear(); visibleChildren.clear(); @@ -91,23 +85,23 @@ int FileSortWorker::childrenCount() return visibleChildren.count(); } -FileItemData *FileSortWorker::childData(const QUrl &url) +FileItemDataPointer FileSortWorker::childData(const QUrl &url) { QReadLocker lk(&childrenDataLocker); return childrenDataMap.value(url); } -void FileSortWorker::setRootData(FileItemData *data) +void FileSortWorker::setRootData(const FileItemDataPointer data) { rootdata = data; } -FileItemData *FileSortWorker::rootData() const +FileItemDataPointer FileSortWorker::rootData() const { return rootdata; } -FileItemData *FileSortWorker::childData(const int index) +FileItemDataPointer FileSortWorker::childData(const int index) { QUrl url; { @@ -162,11 +156,12 @@ void FileSortWorker::handleIteratorLocalChildren(const QString &key, if (currentKey != key) return; + childrenDataLastMap.clear(); this->children = children; for (const auto &child : children) { childrenUrlList.append(child->fileUrl()); QWriteLocker lk(&childrenDataLocker); - childrenDataMap.insert(child->fileUrl(), new FileItemData(child, rootdata)); + childrenDataMap.insert(child->fileUrl(), FileItemDataPointer(new FileItemData(child, rootdata.data()))); } if (isCanceled) @@ -196,6 +191,7 @@ void FileSortWorker::handleSourceChildren(const QString &key, if (currentKey != key) return; + childrenDataLastMap.clear(); if (this->childrenUrlList.isEmpty()) { handleIteratorLocalChildren(key, children, sortRole, sortOrder, isMixDirAndFile); if (isFinished) { @@ -215,7 +211,7 @@ void FileSortWorker::handleSourceChildren(const QString &key, this->childrenUrlList.append(sortInfo->fileUrl()); { QWriteLocker lk(&childrenDataLocker); - childrenDataMap.insert(sortInfo->fileUrl(), new FileItemData(sortInfo, rootdata)); + childrenDataMap.insert(sortInfo->fileUrl(), FileItemDataPointer(new FileItemData(sortInfo, rootdata.data()))); } if (checkFilters(sortInfo)) newChildren.append(sortInfo->fileUrl()); @@ -278,6 +274,8 @@ void FileSortWorker::handleIteratorChild(const QString &key, const SortInfoPoint if (!child) return; + childrenDataLastMap.clear(); + addChild(child, info); } @@ -288,6 +286,7 @@ void FileSortWorker::handleIteratorChildren(const QString &key, QListfileUrl()); { QWriteLocker lk(&childrenDataLocker); - childrenDataMap.insert(sortInfo->fileUrl(), new FileItemData(sortInfo->fileUrl(), infos.at(i), rootdata)); + childrenDataMap.insert(sortInfo->fileUrl(), + FileItemDataPointer(new FileItemData(sortInfo->fileUrl(), infos.at(i), rootdata.data()))); } if (!checkFilters(sortInfo)) continue; @@ -344,7 +344,7 @@ void FileSortWorker::setFilters(QDir::Filters filters) void FileSortWorker::setNameFilters(const QStringList &filters) { nameFilters = filters; - QMap::iterator itr = childrenDataMap.begin(); + QMap::iterator itr = childrenDataMap.begin(); for (; itr != childrenDataMap.end(); ++itr) { checkNameFilters(itr.value()); } @@ -625,8 +625,9 @@ void FileSortWorker::handleRefresh() { QWriteLocker lk(&childrenDataLocker); childrenUrlList.clear(); - qDeleteAll(childrenDataMap.values()); + childrenDataLastMap = childrenDataMap; childrenDataMap.clear(); + } if (!empty) @@ -667,7 +668,7 @@ void FileSortWorker::handleFileInfoUpdated(const QUrl &url, const QString &infoP handleUpdateFile(url); } -void FileSortWorker::checkNameFilters(FileItemData *itemData) +void FileSortWorker::checkNameFilters(const FileItemDataPointer itemData) { if (!itemData || itemData->data(Global::ItemRoles::kItemFileIsDirRole).toBool() || nameFilters.isEmpty()) return; @@ -936,7 +937,8 @@ void FileSortWorker::addChild(const SortInfoPointer &sortInfo, const FileInfoPoi childrenUrlList.append(sortInfo->fileUrl()); { QWriteLocker lk(&childrenDataLocker); - childrenDataMap.insert(sortInfo->fileUrl(), new FileItemData(sortInfo->fileUrl(), info, rootdata)); + childrenDataMap.insert(sortInfo->fileUrl(), + FileItemDataPointer(new FileItemData(sortInfo->fileUrl(), info, rootdata.data()))); } if (!checkFilters(sortInfo)) return; @@ -972,13 +974,13 @@ void FileSortWorker::addChild(const SortInfoPointer &sortInfo, childrenUrlList.append(sortInfo->fileUrl()); { auto info = InfoFactory::create(sortInfo->fileUrl()); - FileItemData *item{nullptr}; + FileItemDataPointer item{nullptr}; if (info) { info->refresh(); - item = new FileItemData(sortInfo->fileUrl(), info, rootdata); + item.reset(new FileItemData(sortInfo->fileUrl(), info, rootdata.data())); item->setSortFileInfo(sortInfo); } else { - item = new FileItemData(sortInfo, rootdata); + item.reset(new FileItemData(sortInfo, rootdata.data())); } QWriteLocker lk(&childrenDataLocker); diff --git a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.h b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.h index c73909d98c..b1e7988e0a 100644 --- a/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.h +++ b/src/plugins/filemanager/core/dfmplugin-workspace/utils/filesortworker.h @@ -6,6 +6,7 @@ #define FILESORTWORKER_H #include "dfmplugin_workspace_global.h" +#include "models/fileitemdata.h" #include #include #include @@ -21,7 +22,6 @@ using namespace dfmbase; namespace dfmplugin_workspace { -class FileItemData; class FileSortWorker : public QObject { Q_OBJECT @@ -44,10 +44,10 @@ class FileSortWorker : public QObject const bool isMixDirAndFile); QUrl mapToIndex(int index); int childrenCount(); - FileItemData *childData(const int index); - FileItemData *childData(const QUrl &url); - void setRootData(FileItemData *data); - FileItemData *rootData() const; + FileItemDataPointer childData(const int index); + FileItemDataPointer childData(const QUrl &url); + void setRootData(const FileItemDataPointer data); + FileItemDataPointer rootData() const; void cancel(); int getChildShowIndex(const QUrl &url); QList getChildrenUrls(); @@ -115,7 +115,7 @@ public slots: void handleFileInfoUpdated(const QUrl &url, const QString &infoPtr, const bool isLinkOrg); private: - void checkNameFilters(FileItemData *itemData); + void checkNameFilters(const FileItemDataPointer itemData); bool checkFilters(const SortInfoPointer &sortInfo, const bool byInfo = false); void filterAllFiles(const bool byInfo = false); void filterAllFilesOrdered(); @@ -142,13 +142,14 @@ public slots: QList children {}; QList childrenUrlList {}; QReadWriteLock childrenDataLocker; - QMap childrenDataMap {}; + QMap childrenDataMap {}; + QMap childrenDataLastMap {}; QList visibleChildren {}; QReadWriteLock locker; AbstractSortFilterPointer sortAndFilter { nullptr }; FileViewFilterCallback filterCallback { nullptr }; QVariant filterData; - FileItemData *rootdata { nullptr }; + FileItemDataPointer rootdata { nullptr }; QString currentKey; Global::ItemRoles orgSortRole { Global::ItemRoles::kItemDisplayRole }; Qt::SortOrder sortOrder { Qt::AscendingOrder };