]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Only access the data of the thread that has been created most recently. Data of older...
authorPeter Penz <peter.penz19@gmail.com>
Sun, 28 Feb 2010 21:03:58 +0000 (21:03 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Sun, 28 Feb 2010 21:03:58 +0000 (21:03 +0000)
svn path=/trunk/KDE/kdebase/apps/; revision=1097289

src/panels/information/kloadmetadatathread.cpp
src/panels/information/kloadmetadatathread_p.h
src/panels/information/kmetadatawidget.cpp

index e95aca404588cbd0e2d9766061f07fda799ef307..fc353c4935a10318b9141948aa6a1b2207f3d706 100644 (file)
@@ -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().
     }
 }
index fddb01a1a26f8dad518f453807561887adc38c43..6aba52ad31dee9f74aba5fba30942a9f7243a019 100644 (file)
@@ -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
index ebcaca211c89c646d344121c04d749e7a96ee8b0..b10e04f336c563c2f2264fb776f0d743545bc032 100644 (file)
@@ -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
 }