From eb697d7a3b7fc8b8af052b6f025610dd85eb176b Mon Sep 17 00:00:00 2001 From: Arno Date: Tue, 25 Jun 2013 20:02:41 +0200 Subject: Fix random crashes in ArchiveCollector This was a hard one, actually. Since we only returned a pointer from the ArchiveCollector, it worked _most_ of the time, but crashed at random when the view was reading the tree while the collector was updating it. So create a working copy constructor for SmRootItem and return a copy of the the tree when the collector is done. I bet that's also the reason for the random crashes in the filesystem view. --- archivemodel.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'archivemodel.cpp') diff --git a/archivemodel.cpp b/archivemodel.cpp index b0a6941..86a478e 100644 --- a/archivemodel.cpp +++ b/archivemodel.cpp @@ -5,8 +5,8 @@ 2 of the License, or (at your option) any later version. */ -#include #include +#include #include #include #include @@ -102,7 +102,9 @@ bool ArchiveModel::setData(const QModelIndex &idx, const QVariant &value, int ro QVariant id = item->data(GenericId); updateQuery.bindValue(":value", value); updateQuery.bindValue(":id", id); + mDb.transaction(); if(updateQuery.exec()){ + mDb.commit(); item->setData(Name, value); emit dataChanged(idx, idx); if(nodeType == SeriesNode){ @@ -110,8 +112,8 @@ bool ArchiveModel::setData(const QModelIndex &idx, const QVariant &value, int ro return true; } writeCache(mOrder, root()); - return true; }else{ + mDb.rollback(); emitDatabaseError(updateQuery.lastError()); } return false; @@ -226,22 +228,23 @@ void ArchiveModel::setOrder(const QString &order){ void ArchiveModel::refresh(){ emit message(tr("Reading archive data...")); foreach(ArchiveCollector *c, mCollectors){ - c->start(); + if(!c->isRunning()){ + c->start(); + } } } void ArchiveModel::collectorFinished(QObject *thread){ QMutexLocker l(&mDoneMx); ArchiveCollector *t = qobject_cast(thread); - Q_ASSERT(t); - SmTreeItem *item = t->rootItem(); + SmTreeItem *rootCopy = t->rootItem(); int sortOrder = t->sortOrder(); if(sortOrder == mOrder){ emit collectorAboutToBeDone(); - setRoot(item); + setRoot(rootCopy); emit collectorDone(); } - writeCache(sortOrder, item); + writeCache(sortOrder, rootCopy); QString sortOrderName = mAvailableOrders.key(sortOrder); QString msg = QString("Done reading %1").arg(sortOrderName); emit message(msg); @@ -353,14 +356,24 @@ const QString ArchiveModel::cacheFile(int o) const{ return cacheFile; } -ArchiveCollector::ArchiveCollector(int numFields, int order, QObject *parent) : QThread(parent), mNumFields(numFields), mSortOrder(order) { +ArchiveCollector::ArchiveCollector(int numFields, int order, QObject *parent) : QThread(parent), mRootItem(0), mNumFields(numFields), mSortOrder(order) { QString dbName = QString("%1").arg((qint64(this))); mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), dbName); mDb.open(); - mRootItem = new SmTreeItem(numFields); + //mRootItem = new SmTreeItem(numFields); +} + +SmTreeItem *ArchiveCollector::rootItem(){ + mAccessMx.lock(); + SmTreeItem *retval = new SmTreeItem(*mRootItem); + mAccessMx.unlock(); + return retval; } void ArchiveCollector::run(){ + mAccessMx.lock(); + delete mRootItem; + mRootItem = new SmTreeItem(mNumFields); switch (mSortOrder){ case ArchiveModel::SeriesName: populateBySeriesName(); @@ -374,6 +387,7 @@ void ArchiveCollector::run(){ default: return; } + mAccessMx.unlock(); } void ArchiveCollector::populateBySeriesName() { -- cgit v1.2.3-70-g09d2