From: Peter Penz Date: Sun, 28 Feb 2010 21:03:58 +0000 (+0000) Subject: Only access the data of the thread that has been created most recently. Data of older... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a0b010bb00fe10f2b3e927ff0c465839d6993b84 Only access the data of the thread that has been created most recently. Data of older threads will just get ignored. svn path=/trunk/KDE/kdebase/apps/; revision=1097289 --- diff --git a/src/panels/information/kloadmetadatathread.cpp b/src/panels/information/kloadmetadatathread.cpp index e95aca404..fc353c493 100644 --- a/src/panels/information/kloadmetadatathread.cpp +++ b/src/panels/information/kloadmetadatathread.cpp @@ -53,6 +53,13 @@ void KLoadMetaDataThread::load(const KUrl::List& urls) start(); } +void KLoadMetaDataThread::cancel() +{ + // Setting m_canceled to true will cancel KLoadMetaDataThread::run() + // as soon as run() gets the chance to check m_cancel. + m_canceled = true; +} + void KLoadMetaDataThread::cancelAndDelete() { if (isFinished()) { @@ -60,9 +67,10 @@ void KLoadMetaDataThread::cancelAndDelete() deleteLater(); } else { connect(this, SIGNAL(finished()), this, SLOT(slotFinished())); - m_canceled = true; // Setting m_canceled to true will cancel KLoadMetaDataThread::run() - // as soon as possible. Afterwards the thread will delete itself + // as soon as run() gets the chance to check m_cancel. + m_canceled = true; + // Afterwards the thread will delete itself // asynchronously inside slotFinished(). } } diff --git a/src/panels/information/kloadmetadatathread_p.h b/src/panels/information/kloadmetadatathread_p.h index fddb01a1a..6aba52ad3 100644 --- a/src/panels/information/kloadmetadatathread_p.h +++ b/src/panels/information/kloadmetadatathread_p.h @@ -56,6 +56,14 @@ public: */ void load(const KUrl::List& urls); + /** + * Tells the thread that it should cancel as soon + * as possible. It is undefined when the thread + * gets cancelled. The signal finished() will emitted + * after the cancelling has been done. + */ + void cancel(); + /** * Cancels the thread and assures that the thread deletes * itself as soon as the cancelling has been successful. In diff --git a/src/panels/information/kmetadatawidget.cpp b/src/panels/information/kmetadatawidget.cpp index ebcaca211..b10e04f33 100644 --- a/src/panels/information/kmetadatawidget.cpp +++ b/src/panels/information/kmetadatawidget.cpp @@ -137,7 +137,8 @@ public: QMap m_files; - KLoadMetaDataThread* m_loadMetaDataThread; + QList m_metaDataThreads; + KLoadMetaDataThread* m_latestMetaDataThread; #endif private: @@ -165,7 +166,8 @@ KMetaDataWidget::Private::Private(KMetaDataWidget* parent) : m_taggingWidget(0), m_commentWidget(0), m_files(), - m_loadMetaDataThread(0), + m_metaDataThreads(), + m_latestMetaDataThread(0), #endif q(parent) { @@ -211,11 +213,15 @@ KMetaDataWidget::Private::Private(KMetaDataWidget* parent) : KMetaDataWidget::Private::~Private() { #ifdef HAVE_NEPOMUK - if (m_loadMetaDataThread != 0) { - disconnect(m_loadMetaDataThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished())); - m_loadMetaDataThread->cancelAndDelete(); - m_loadMetaDataThread = 0; + // If there are still threads that receive meta data, tell them + // that they should cancel as soon as possible. No waiting is done + // here, the threads delete themselves after finishing. + foreach (KLoadMetaDataThread* thread, m_metaDataThreads) { + disconnect(thread, SIGNAL(finished()), q, SLOT(slotLoadingFinished())); + thread->cancelAndDelete(); } + m_metaDataThreads.clear(); + m_latestMetaDataThread = 0; #endif } @@ -374,26 +380,36 @@ void KMetaDataWidget::Private::updateRowsVisibility() void KMetaDataWidget::Private::slotLoadingFinished() { #ifdef HAVE_NEPOMUK - if (m_loadMetaDataThread == 0) { - // The signal finished() has been emitted, but the thread has been marked - // as invalid in the meantime. Just ignore the signal in this case. - return; + // The thread that has emitted the finished() signal + // will get deleted and removed from m_metaDataThreads. + const int threadsCount = m_metaDataThreads.count(); + for (int i = 0; i < threadsCount; ++i) { + KLoadMetaDataThread* thread = m_metaDataThreads[i]; + if (thread == q->sender()) { + m_metaDataThreads.removeAt(i); + if (thread != m_latestMetaDataThread) { + // Ignore data of older threads, as the data got + // obsolete by m_latestMetaDataThread. + thread->deleteLater(); + return; + } + } } if (m_nepomukActivated) { Q_ASSERT(m_ratingWidget != 0); Q_ASSERT(m_commentWidget != 0); Q_ASSERT(m_taggingWidget != 0); - m_ratingWidget->setRating(m_loadMetaDataThread->rating()); - m_commentWidget->setText(m_loadMetaDataThread->comment()); - m_taggingWidget->setTags(m_loadMetaDataThread->tags()); + m_ratingWidget->setRating(m_latestMetaDataThread->rating()); + m_commentWidget->setText(m_latestMetaDataThread->comment()); + m_taggingWidget->setTags(m_latestMetaDataThread->tags()); } // Show the remaining meta information as text. The number // of required rows may very. Existing rows are reused to // prevent flickering. int rowIndex = m_fixedRowCount; - const QList items = mergedItems(m_loadMetaDataThread->items()); + const QList items = mergedItems(m_latestMetaDataThread->items()); foreach (const KLoadMetaDataThread::Item& item, items) { const QString itemLabel = item.label; QString itemValue = item.value; @@ -434,12 +450,8 @@ void KMetaDataWidget::Private::slotLoadingFinished() m_rows.pop_back(); } - m_files = m_loadMetaDataThread->files(); - - Q_ASSERT(!m_loadMetaDataThread->isRunning()); - Q_ASSERT(m_loadMetaDataThread->isFinished()); - m_loadMetaDataThread->deleteLater(); - m_loadMetaDataThread = 0; + m_files = m_latestMetaDataThread->files(); + m_latestMetaDataThread->deleteLater(); #endif q->updateGeometry(); @@ -612,14 +624,17 @@ void KMetaDataWidget::setItems(const KFileItemList& items) } } - if (d->m_loadMetaDataThread != 0) { - disconnect(d->m_loadMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished())); - d->m_loadMetaDataThread->cancelAndDelete(); + // Cancel all threads that have not emitted a finished() signal. + // The deleting of those threads is done in slotLoadingFinished(). + foreach (KLoadMetaDataThread* thread, d->m_metaDataThreads) { + thread->cancel(); } - d->m_loadMetaDataThread = new KLoadMetaDataThread(); - connect(d->m_loadMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished())); - d->m_loadMetaDataThread->load(urls); + // create a new thread that will provide the meeta data for the items + d->m_latestMetaDataThread = new KLoadMetaDataThread(); + connect(d->m_latestMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished())); + d->m_latestMetaDataThread->load(urls); + d->m_metaDataThreads.append(d->m_latestMetaDataThread); #endif }