Get rid of recursive mutex.

This commit is contained in:
Adam Treat 2023-06-25 20:22:38 -04:00
parent 7f01b153b3
commit 27f25d5878
2 changed files with 100 additions and 90 deletions

View File

@ -166,23 +166,26 @@ bool ModelList::lessThan(const ModelInfo* a, const ModelInfo* b)
void ModelList::addModel(const QString &filename) void ModelList::addModel(const QString &filename)
{ {
QMutexLocker locker(&m_mutex); const bool hasModel = contains(filename);
Q_ASSERT(!m_modelMap.contains(filename)); Q_ASSERT(!hasModel);
if (m_modelMap.contains(filename)) { if (hasModel) {
qWarning() << "ERROR: model list already contains" << filename; qWarning() << "ERROR: model list already contains" << filename;
return; return;
} }
beginInsertRows(QModelIndex(), m_models.size(), m_models.size()); beginInsertRows(QModelIndex(), m_models.size(), m_models.size());
ModelInfo *info = new ModelInfo; int modelSizeAfter = 0;
info->filename = filename; {
m_models.append(info); QMutexLocker locker(&m_mutex);
m_modelMap.insert(filename, info); ModelInfo *info = new ModelInfo;
info->filename = filename;
m_models.append(info);
m_modelMap.insert(filename, info);
std::stable_sort(m_models.begin(), m_models.end(), ModelList::lessThan);
modelSizeAfter = m_models.size();
}
endInsertRows(); endInsertRows();
emit dataChanged(index(0, 0), index(modelSizeAfter - 1, 0));
std::stable_sort(m_models.begin(), m_models.end(), ModelList::lessThan);
emit dataChanged(index(0, 0), index(m_models.size() - 1, 0));
emit userDefaultModelListChanged(); emit userDefaultModelListChanged();
} }
@ -271,88 +274,95 @@ QVariant ModelList::data(const QModelIndex &index, int role) const
void ModelList::updateData(const QString &filename, int role, const QVariant &value) void ModelList::updateData(const QString &filename, int role, const QVariant &value)
{ {
QMutexLocker locker(&m_mutex); int modelSize;
if (!m_modelMap.contains(filename)) { bool updateInstalled;
qWarning() << "ERROR: cannot update as model map does not contain" << filename; bool updateIncomplete;
return; int index;
} {
QMutexLocker locker(&m_mutex);
if (!m_modelMap.contains(filename)) {
qWarning() << "ERROR: cannot update as model map does not contain" << filename;
return;
}
ModelInfo *info = m_modelMap.value(filename); ModelInfo *info = m_modelMap.value(filename);
const int index = m_models.indexOf(info); index = m_models.indexOf(info);
if (index == -1) { if (index == -1) {
qWarning() << "ERROR: cannot update as model list does not contain" << filename; qWarning() << "ERROR: cannot update as model list does not contain" << filename;
return; return;
} }
switch (role) { switch (role) {
case NameRole: case NameRole:
info->name = value.toString(); break; info->name = value.toString(); break;
case FilenameRole: case FilenameRole:
info->filename = value.toString(); break; info->filename = value.toString(); break;
case DirpathRole: case DirpathRole:
info->dirpath = value.toString(); break; info->dirpath = value.toString(); break;
case FilesizeRole: case FilesizeRole:
info->filesize = value.toString(); break; info->filesize = value.toString(); break;
case Md5sumRole: case Md5sumRole:
info->md5sum = value.toByteArray(); break; info->md5sum = value.toByteArray(); break;
case CalcHashRole: case CalcHashRole:
info->calcHash = value.toBool(); break; info->calcHash = value.toBool(); break;
case InstalledRole: case InstalledRole:
info->installed = value.toBool(); break; info->installed = value.toBool(); break;
case DefaultRole: case DefaultRole:
info->isDefault = value.toBool(); break; info->isDefault = value.toBool(); break;
case ChatGPTRole: case ChatGPTRole:
info->isChatGPT = value.toBool(); break; info->isChatGPT = value.toBool(); break;
case DisableGUIRole: case DisableGUIRole:
info->disableGUI = value.toBool(); break; info->disableGUI = value.toBool(); break;
case DescriptionRole: case DescriptionRole:
info->description = value.toString(); break; info->description = value.toString(); break;
case RequiresVersionRole: case RequiresVersionRole:
info->requiresVersion = value.toString(); break; info->requiresVersion = value.toString(); break;
case DeprecatedVersionRole: case DeprecatedVersionRole:
info->deprecatedVersion = value.toString(); break; info->deprecatedVersion = value.toString(); break;
case UrlRole: case UrlRole:
info->url = value.toString(); break; info->url = value.toString(); break;
case BytesReceivedRole: case BytesReceivedRole:
info->bytesReceived = value.toLongLong(); break; info->bytesReceived = value.toLongLong(); break;
case BytesTotalRole: case BytesTotalRole:
info->bytesTotal = value.toLongLong(); break; info->bytesTotal = value.toLongLong(); break;
case TimestampRole: case TimestampRole:
info->timestamp = value.toLongLong(); break; info->timestamp = value.toLongLong(); break;
case SpeedRole: case SpeedRole:
info->speed = value.toString(); break; info->speed = value.toString(); break;
case DownloadingRole: case DownloadingRole:
info->isDownloading = value.toBool(); break; info->isDownloading = value.toBool(); break;
case IncompleteRole: case IncompleteRole:
info->isIncomplete = value.toBool(); break; info->isIncomplete = value.toBool(); break;
case DownloadErrorRole: case DownloadErrorRole:
info->downloadError = value.toString(); break; info->downloadError = value.toString(); break;
case OrderRole: case OrderRole:
info->order = value.toString(); break; info->order = value.toString(); break;
case RamrequiredRole: case RamrequiredRole:
info->ramrequired = value.toInt(); break; info->ramrequired = value.toInt(); break;
case ParametersRole: case ParametersRole:
info->parameters = value.toString(); break; info->parameters = value.toString(); break;
case QuantRole: case QuantRole:
info->quant = value.toString(); break; info->quant = value.toString(); break;
case TypeRole: case TypeRole:
info->type = value.toString(); break; info->type = value.toString(); break;
} }
// Extra guarantee that these always remains in sync with filesystem // Extra guarantee that these always remains in sync with filesystem
QFileInfo fileInfo(info->dirpath + info->filename); QFileInfo fileInfo(info->dirpath + info->filename);
if (info->installed != fileInfo.exists()) { if (info->installed != fileInfo.exists()) {
info->installed = fileInfo.exists(); info->installed = fileInfo.exists();
emit dataChanged(createIndex(index, 0), createIndex(index, 0), {InstalledRole}); updateInstalled = true;
} }
QFileInfo incompleteInfo(incompleteDownloadPath(info->filename)); QFileInfo incompleteInfo(incompleteDownloadPath(info->filename));
if (info->isIncomplete != incompleteInfo.exists()) { if (info->isIncomplete != incompleteInfo.exists()) {
info->isIncomplete = incompleteInfo.exists(); info->isIncomplete = incompleteInfo.exists();
emit dataChanged(createIndex(index, 0), createIndex(index, 0), {IncompleteRole}); updateIncomplete = true;
} }
std::stable_sort(m_models.begin(), m_models.end(), ModelList::lessThan); std::stable_sort(m_models.begin(), m_models.end(), ModelList::lessThan);
emit dataChanged(createIndex(0, 0), createIndex(m_models.size() - 1, 0)); modelSize = m_models.size();
}
emit dataChanged(createIndex(0, 0), createIndex(modelSize - 1, 0));
emit userDefaultModelListChanged(); emit userDefaultModelListChanged();
} }

View File

@ -229,7 +229,7 @@ private:
static bool lessThan(const ModelInfo* a, const ModelInfo* b); static bool lessThan(const ModelInfo* a, const ModelInfo* b);
private: private:
mutable QRecursiveMutex m_mutex; mutable QMutex m_mutex;
InstalledModels *m_installedModels; InstalledModels *m_installedModels;
DownloadableModels *m_downloadableModels; DownloadableModels *m_downloadableModels;
QList<ModelInfo*> m_models; QList<ModelInfo*> m_models;