modellist: assert that update functions are called from main thread

The locking strategy used by ModelList assumes that only one thread will
be trying to update the model list at a time, as writes cannot be
implemented in a fully threadsafe manner.

Signed-off-by: Jared Van Bortel <jared@nomic.ai>
This commit is contained in:
Jared Van Bortel 2024-10-04 18:29:15 -04:00
parent 3dea7e2bfa
commit d0158d2013

View File

@ -632,6 +632,7 @@ bool ModelList::lessThan(const ModelInfo* a, const ModelInfo* b, DiscoverSort s,
void ModelList::addModel(const QString &id) void ModelList::addModel(const QString &id)
{ {
Q_ASSERT(QThread::currentThread() == thread());
const bool hasModel = contains(id); const bool hasModel = contains(id);
Q_ASSERT(!hasModel); Q_ASSERT(!hasModel);
if (hasModel) { if (hasModel) {
@ -820,6 +821,7 @@ QVariant ModelList::data(const QModelIndex &index, int role) const
void ModelList::updateData(const QString &id, const QVector<QPair<int, QVariant>> &data) void ModelList::updateData(const QString &id, const QVector<QPair<int, QVariant>> &data)
{ {
Q_ASSERT(QThread::currentThread() == thread());
int index; int index;
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
@ -1028,6 +1030,7 @@ void ModelList::resortModel()
void ModelList::updateDataByFilename(const QString &filename, QVector<QPair<int, QVariant>> data) void ModelList::updateDataByFilename(const QString &filename, QVector<QPair<int, QVariant>> data)
{ {
Q_ASSERT(QThread::currentThread() == thread());
if (data.isEmpty()) if (data.isEmpty())
return; // no-op return; // no-op
@ -1076,6 +1079,7 @@ bool ModelList::isUniqueName(const QString &name) const
QString ModelList::clone(const ModelInfo &model) QString ModelList::clone(const ModelInfo &model)
{ {
Q_ASSERT(QThread::currentThread() == thread());
const QString id = Network::globalInstance()->generateUniqueId(); const QString id = Network::globalInstance()->generateUniqueId();
addModel(id); addModel(id);
@ -1109,6 +1113,7 @@ QString ModelList::clone(const ModelInfo &model)
void ModelList::removeClone(const ModelInfo &model) void ModelList::removeClone(const ModelInfo &model)
{ {
Q_ASSERT(QThread::currentThread() == thread());
Q_ASSERT(model.isClone()); Q_ASSERT(model.isClone());
if (!model.isClone()) if (!model.isClone())
return; return;
@ -1119,6 +1124,7 @@ void ModelList::removeClone(const ModelInfo &model)
void ModelList::removeInstalled(const ModelInfo &model) void ModelList::removeInstalled(const ModelInfo &model)
{ {
Q_ASSERT(QThread::currentThread() == thread());
Q_ASSERT(model.installed); Q_ASSERT(model.installed);
Q_ASSERT(!model.isClone()); Q_ASSERT(!model.isClone());
Q_ASSERT(model.isDiscovered() || model.isCompatibleApi || model.description() == "" /*indicates sideloaded*/); Q_ASSERT(model.isDiscovered() || model.isCompatibleApi || model.description() == "" /*indicates sideloaded*/);
@ -1128,6 +1134,7 @@ void ModelList::removeInstalled(const ModelInfo &model)
void ModelList::removeInternal(const ModelInfo &model) void ModelList::removeInternal(const ModelInfo &model)
{ {
Q_ASSERT(QThread::currentThread() == thread());
const bool hasModel = contains(model.id()); const bool hasModel = contains(model.id());
Q_ASSERT(hasModel); Q_ASSERT(hasModel);
if (!hasModel) { if (!hasModel) {
@ -1325,6 +1332,7 @@ void ModelList::processModelDirectory(const QString &path)
void ModelList::updateModelsFromDirectory() void ModelList::updateModelsFromDirectory()
{ {
Q_ASSERT(QThread::currentThread() == thread());
const QString exePath = QCoreApplication::applicationDirPath() + QDir::separator(); const QString exePath = QCoreApplication::applicationDirPath() + QDir::separator();
const QString localPath = MySettings::globalInstance()->modelPath(); const QString localPath = MySettings::globalInstance()->modelPath();
@ -1727,6 +1735,7 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
void ModelList::updateDiscoveredInstalled(const ModelInfo &info) void ModelList::updateDiscoveredInstalled(const ModelInfo &info)
{ {
Q_ASSERT(QThread::currentThread() == thread());
QVector<QPair<int, QVariant>> data { QVector<QPair<int, QVariant>> data {
{ ModelList::InstalledRole, true }, { ModelList::InstalledRole, true },
{ ModelList::IsDiscoveredRole, true }, { ModelList::IsDiscoveredRole, true },
@ -1937,6 +1946,7 @@ bool ModelList::discoverInProgress() const
void ModelList::discoverSearch(const QString &search) void ModelList::discoverSearch(const QString &search)
{ {
Q_ASSERT(QThread::currentThread() == thread());
Q_ASSERT(!m_discoverInProgress); Q_ASSERT(!m_discoverInProgress);
clearDiscoveredModels(); clearDiscoveredModels();