diff options
author | Arno <am@disconnect.de> | 2013-06-25 20:02:41 +0200 |
---|---|---|
committer | Arno <am@disconnect.de> | 2013-06-25 20:02:41 +0200 |
commit | eb697d7a3b7fc8b8af052b6f025610dd85eb176b (patch) | |
tree | 04c410b656baf129d3e5bfcdb4ead80f15fba4ea /archivemodel.cpp | |
parent | ae1582fa29de82c28872f826fa6f8b154bea88dc (diff) | |
download | SheMov-eb697d7a3b7fc8b8af052b6f025610dd85eb176b.tar.gz SheMov-eb697d7a3b7fc8b8af052b6f025610dd85eb176b.tar.bz2 SheMov-eb697d7a3b7fc8b8af052b6f025610dd85eb176b.zip |
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.
Diffstat (limited to 'archivemodel.cpp')
-rw-r--r-- | archivemodel.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
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 <QSqlError> #include <QSqlQuery> +#include <QSqlError> #include <QFile> #include <QSettings> #include <QMutexLocker> @@ -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<ArchiveCollector*>(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() { |