┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2010-02-28 21:03:58 +0000
committerPeter Penz <[email protected]>2010-02-28 21:03:58 +0000
commita0b010bb00fe10f2b3e927ff0c465839d6993b84 (patch)
tree09973a2b529582e0b603e3a37bf44b104a682edf /src
parent072dacbb552cd743d99eb811aa4a2ddf4844090a (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/panels/information/kloadmetadatathread.cpp12
-rw-r--r--src/panels/information/kloadmetadatathread_p.h8
-rw-r--r--src/panels/information/kmetadatawidget.cpp67
3 files changed, 59 insertions, 28 deletions
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
@@ -57,6 +57,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
* opposite to QThread::wait() the caller of cancelAndDelete()
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<KUrl, Nepomuk::Resource> m_files;
- KLoadMetaDataThread* m_loadMetaDataThread;
+ QList<KLoadMetaDataThread*> 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<KLoadMetaDataThread::Item> items = mergedItems(m_loadMetaDataThread->items());
+ const QList<KLoadMetaDataThread::Item> 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
}