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 <flowlnlnln@gmail.com>
This commit is contained in:
flow 2022-12-15 13:51:07 -03:00
parent b0c866bfaa
commit c440f33122
No known key found for this signature in database
GPG Key ID: 8D0F221F0A59F469
2 changed files with 8 additions and 1 deletions

View File

@ -20,6 +20,7 @@ ResourceFolderModel::ResourceFolderModel(QDir dir, QObject* parent) : QAbstractL
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged); connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged);
connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this]{ m_helper_thread_task.clear(); });
} }
ResourceFolderModel::~ResourceFolderModel() ResourceFolderModel::~ResourceFolderModel()
@ -275,7 +276,11 @@ void ResourceFolderModel::resolveResource(Resource* res)
connect( connect(
task, &Task::finished, this, [=] { m_active_parse_tasks.remove(ticket); }, Qt::ConnectionType::QueuedConnection); 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() void ResourceFolderModel::onUpdateSucceeded()

View File

@ -10,6 +10,7 @@
#include "Resource.h" #include "Resource.h"
#include "tasks/Task.h" #include "tasks/Task.h"
#include "tasks/ConcurrentTask.h"
class QSortFilterProxyModel; 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. // Represents the relationship between a resource's internal ID and it's row position on the model.
QMap<QString, int> m_resources_index; QMap<QString, int> m_resources_index;
ConcurrentTask m_helper_thread_task;
QMap<int, Task::Ptr> m_active_parse_tasks; QMap<int, Task::Ptr> m_active_parse_tasks;
std::atomic<int> m_next_resolution_ticket = 0; std::atomic<int> m_next_resolution_ticket = 0;
}; };