From c440f331226b3cc32fac6269d88758a4a0c23fc0 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 15 Dec 2022 13:51:07 -0300 Subject: [PATCH] fix(ResourceModel): use a single ConcurrentTask for parsing tasks This avoids creating a bunch of threads that fills up the maximum amount allowed by QThreadPool, and causes a deadlock between the helper threads and the main thread (main thread tries to create threads in painting code, but isn't able to, so it keeps waiting for a thread to free up, but all the threads are waiting on the main thread to process some events). Signed-off-by: flow --- launcher/minecraft/mod/ResourceFolderModel.cpp | 7 ++++++- launcher/minecraft/mod/ResourceFolderModel.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 0310c8f6..a52c5db3 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -20,6 +20,7 @@ ResourceFolderModel::ResourceFolderModel(QDir dir, QObject* parent) : QAbstractL m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged); + connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this]{ m_helper_thread_task.clear(); }); } ResourceFolderModel::~ResourceFolderModel() @@ -275,7 +276,11 @@ void ResourceFolderModel::resolveResource(Resource* res) connect( task, &Task::finished, this, [=] { m_active_parse_tasks.remove(ticket); }, Qt::ConnectionType::QueuedConnection); - QThreadPool::globalInstance()->start(task); + m_helper_thread_task.addTask(task); + + if (!m_helper_thread_task.isRunning()) { + QThreadPool::globalInstance()->start(&m_helper_thread_task); + } } void ResourceFolderModel::onUpdateSucceeded() diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index fe283b04..f1bc2dd7 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -10,6 +10,7 @@ #include "Resource.h" #include "tasks/Task.h" +#include "tasks/ConcurrentTask.h" class QSortFilterProxyModel; @@ -197,6 +198,7 @@ class ResourceFolderModel : public QAbstractListModel { // Represents the relationship between a resource's internal ID and it's row position on the model. QMap m_resources_index; + ConcurrentTask m_helper_thread_task; QMap m_active_parse_tasks; std::atomic m_next_resolution_ticket = 0; };