[SCM] KDE Development Platform Libraries module packaging branch, wheezy, updated. debian/4.8.4-4-7-g8a1b2ac

Pino Toscano pino at alioth.debian.org
Tue Dec 4 14:42:29 UTC 2012


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-sc/kde4libs.git;a=commitdiff;h=8a1b2ac

The following commit has been merged in the wheezy branch:
commit 8a1b2acb9408bb56460b03ed0d9e860da5b62f68
Author: Pino Toscano <pino at debian.org>
Date:   Tue Dec 4 15:42:02 2012 +0100

    fix file watching in some occasions (#551910)
    
    backport upstream commit 75da8e8129f6bc152a781ff47fb8e741c65b584e
---
 debian/changelog                                   |    4 +
 debian/patches/series                              |    1 +
 ...ter-forgetting-to-watch-a-directory-after.patch |  224 ++++++++++++++++++++
 3 files changed, 229 insertions(+), 0 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index a9b7fcf..499b8ac 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,6 +11,10 @@ kde4libs (4:4.8.4-5) UNRELEASED; urgency=low
     the supported protocols for in-memory services (related to #685980);
     patch upstream_Temp-services-don-t-have-details-so-assume-they-supp.patch.
     (Closes: #695133)
+  * Backport upstream commit 75da8e8129f6bc152a781ff47fb8e741c65b584e to fix
+    file watching in some occasions; patch
+    upstream_Fix-KDirLister-forgetting-to-watch-a-directory-after.patch.
+    (Closes: #551910)
 
  -- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org>  Sat, 27 Oct 2012 17:04:46 -0300
 
diff --git a/debian/patches/series b/debian/patches/series
index 90c9679..98535f8 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -28,3 +28,4 @@ python3-support-bytecode.patch
 fix-copying-of-files-with-extended-ACLs.patch
 upstream_Fix-parsing-of-the-Keywords-key-in-.desktop-files-no.patch
 upstream_Temp-services-don-t-have-details-so-assume-they-supp.patch
+upstream_Fix-KDirLister-forgetting-to-watch-a-directory-after.patch
diff --git a/debian/patches/upstream_Fix-KDirLister-forgetting-to-watch-a-directory-after.patch b/debian/patches/upstream_Fix-KDirLister-forgetting-to-watch-a-directory-after.patch
new file mode 100644
index 0000000..b008fd6
--- /dev/null
+++ b/debian/patches/upstream_Fix-KDirLister-forgetting-to-watch-a-directory-after.patch
@@ -0,0 +1,224 @@
+From 75da8e8129f6bc152a781ff47fb8e741c65b584e Mon Sep 17 00:00:00 2001
+From: David Faure <faure at kde.org>
+Date: Thu, 29 Nov 2012 17:49:34 +0100
+Subject: [PATCH] Fix KDirLister forgetting to watch a directory after listing
+ it from the cache.
+
+Many many thanks to Frank Reininghaus for the unittest that finally made
+this issue reproduceable, based on feedback from users in the bug report.
+
+The issue: whether to watch a directory with KDirWatch is refcounted.
+Each lister showing the dir counts as one, the cache itself can add one,
+and does so initially. If a dir is modified while it's only in the cache,
+we mark it as dirty, stop watching, and we'll simply update the directory
+when showing it to the user again later. At that point we need to start
+watching it again. The old code would do decr+incr, I "optimized" this in
+7b9cafaaf6af (oct 2010) to fix the bug that (with an initial refcount of 1),
+decr would lead to 0 temporarily.
+However if the item wasn't watched anymore (initial refcount of 0), the decr
+would do nothing (if (c<0) c=0), and the incr would start the watching.
+With 7b9cafaaf6af this all went away (I thought decr+incr==noop), so no watching.
+The proper solution is obviously incr+decr_if_not_done_before_already
+(when the cache stops watching the dir because a change happened).
+
+BUG: 211472
+FIXED-IN: 4.9.4
+---
+ kio/kio/kdirlister.cpp       |   22 +++++++++----
+ kio/kio/kdirlister_p.h       |    4 +++
+ kio/tests/kdirlistertest.cpp |   72 ++++++++++++++++++++++++++++++++++++++++--
+ kio/tests/kdirlistertest.h   |    1 +
+ 4 files changed, 90 insertions(+), 9 deletions(-)
+
+diff --git a/kio/kio/kdirlister.cpp b/kio/kio/kdirlister.cpp
+index 0c18dab..d7de137 100644
+--- a/kio/kio/kdirlister.cpp
++++ b/kio/kio/kdirlister.cpp
+@@ -172,19 +172,23 @@ bool KDirListerCache::listDir( KDirLister *lister, const KUrl& _u,
+ 
+         dirData.listersCurrentlyListing.append(lister);
+ 
+-        DirItem *itemFromCache;
++        DirItem *itemFromCache = 0;
+         if (itemU || (!_reload && (itemFromCache = itemsCached.take(urlStr)) ) ) {
+             if (itemU) {
+                 kDebug(7004) << "Entry already in use:" << _url;
+                 // if _reload is set, then we'll emit cached items and then updateDirectory.
+-                if (lister->d->autoUpdate)
+-                    itemU->incAutoUpdate();
+             } else {
+                 kDebug(7004) << "Entry in cache:" << _url;
+-                // In this code path, the itemsFromCache->decAutoUpdate + itemU->incAutoUpdate is optimized out
+                 itemsInUse.insert(urlStr, itemFromCache);
+                 itemU = itemFromCache;
+             }
++            if (lister->d->autoUpdate) {
++                itemU->incAutoUpdate();
++            }
++            if (itemFromCache && itemFromCache->watchedWhileInCache) {
++                itemFromCache->watchedWhileInCache = false;;
++                itemFromCache->decAutoUpdate();
++            }
+ 
+             emit lister->started(_url);
+ 
+@@ -416,7 +420,7 @@ void KDirListerCache::stop( KDirLister *lister, bool silent )
+     Q_FOREACH(const KUrl& url, urls) {
+         stopListingUrl(lister, url, silent);
+     }
+-    
++
+ #if 0 // test code
+     QHash<QString,KDirListerCacheDirectoryData>::iterator dirit = directoryData.begin();
+     const QHash<QString,KDirListerCacheDirectoryData>::iterator dirend = directoryData.end();
+@@ -618,9 +622,10 @@ void KDirListerCache::forgetDirs( KDirLister *lister, const KUrl& _url, bool not
+                 kDebug(7004) << "Not adding a watch on " << item->url << " because it " <<
+                     ( isManuallyMounted ? "is manually mounted" : "contains a manually mounted subdir" );
+                 item->complete = false; // set to "dirty"
+-            }
+-            else
++            } else {
+                 item->incAutoUpdate(); // keep watch
++                item->watchedWhileInCache = true;
++            }
+         }
+         else
+         {
+@@ -746,7 +751,10 @@ bool KDirListerCache::checkUpdate( const QString& _dir )
+     DirItem *item = itemsCached[_dir];
+     if ( item && item->complete )
+     {
++      // Stop watching items once they are only in the cache and not used anymore.
++      // We'll trigger an update when listing that dir again later.
+       item->complete = false;
++      item->watchedWhileInCache = false;
+       item->decAutoUpdate();
+       // Hmm, this debug output might include login/password from the _dir URL.
+       //kDebug(7004) << "directory " << _dir << " not in use, marked dirty.";
+diff --git a/kio/kio/kdirlister_p.h b/kio/kio/kdirlister_p.h
+index dd4c00f..a78cc3c 100644
+--- a/kio/kio/kdirlister_p.h
++++ b/kio/kio/kdirlister_p.h
+@@ -319,6 +319,7 @@ private:
+     {
+       autoUpdates = 0;
+       complete = false;
++      watchedWhileInCache = false;
+     }
+ 
+     ~DirItem()
+@@ -392,6 +393,9 @@ private:
+     // this directory is up-to-date
+     bool complete;
+ 
++    // the directory is watched while being in the cache (useful for proper incAutoUpdate/decAutoUpdate count)
++    bool watchedWhileInCache;
++
+     // the complete url of this directory
+     KUrl url;
+ 
+diff --git a/kio/tests/kdirlistertest.cpp b/kio/tests/kdirlistertest.cpp
+index 1216b43..b574816 100644
+--- a/kio/tests/kdirlistertest.cpp
++++ b/kio/tests/kdirlistertest.cpp
+@@ -871,6 +871,68 @@ void KDirListerTest::testOpenAndStop()
+     disconnect(&m_dirLister, 0, this, 0);
+ }
+ 
++// A bug in the decAutoUpdate/incAutoUpdate logic made KDirLister stop watching a directory for changes,
++// and never watch it again when opening it from the cache.
++void KDirListerTest::testBug211472()
++{
++    m_items.clear();
++
++    KTempDir newDir;
++    const QString path = newDir.name() + "newsubdir/";
++    QDir().mkdir(path);
++    MyDirLister dirLister;
++    connect(&dirLister, SIGNAL(newItems(KFileItemList)), this, SLOT(slotNewItems(KFileItemList)));
++
++    dirLister.openUrl(KUrl(path));
++    QVERIFY(QTest::kWaitForSignal(&dirLister, SIGNAL(completed()), 1000));
++    QVERIFY(dirLister.isFinished());
++    QVERIFY(m_items.isEmpty());
++
++    if (true) {
++        // This block is required to trigger bug 211472.
++
++        // Go 'up' to the parent of 'newsubdir'.
++        dirLister.openUrl(KUrl(newDir.name()));
++        QVERIFY(QTest::kWaitForSignal(&dirLister, SIGNAL(completed()), 1000));
++        QVERIFY(dirLister.isFinished());
++        QVERIFY(!m_items.isEmpty());
++        m_items.clear();
++
++        // Create a file in 'newsubdir' while we are listing its parent dir.
++        createTestFile(path + "newFile-1");
++        // At this point, newsubdir is not used, so it's moved to the cache.
++        // This happens in checkUpdate, called when receiving a notification for the cached dir,
++        // this is why this unittest needs to create a test file in the subdir.
++        QTest::qWait(1000);
++        QVERIFY(m_items.isEmpty());
++
++        // Return to 'newsubdir'. It will be emitted from the cache, then an update will happen.
++        dirLister.openUrl(KUrl(path));
++        QVERIFY(QTest::kWaitForSignal(&dirLister, SIGNAL(completed()), 1000));
++        QVERIFY(QTest::kWaitForSignal(&dirLister, SIGNAL(completed()), 1000));
++        QVERIFY(dirLister.isFinished());
++        QCOMPARE(m_items.count(), 1);
++        m_items.clear();
++    }
++
++    // Now try to create a second file in 'newsubdir' and verify that the
++    // dir lister notices it.
++    QTest::qWait(1000); // We need a 1s timestamp difference on the dir, otherwise FAM won't notice anything.
++
++    createTestFile(path + "newFile-2");
++
++    int numTries = 0;
++    // Give time for KDirWatch to notify us
++    while (m_items.isEmpty()) {
++        QVERIFY(++numTries < 10);
++        QTest::qWait(200);
++    }
++    QCOMPARE(m_items.count(), 1);
++
++    newDir.unlink();
++    QVERIFY(QTest::kWaitForSignal(&dirLister, SIGNAL(clear()), 1000));
++}
++
+ void KDirListerTest::testRedirection()
+ {
+     m_items.clear();
+@@ -964,8 +1026,14 @@ void KDirListerTest::testDeleteCurrentDir()
+     enterLoop();
+     QCOMPARE(m_dirLister.spyClear.count(), 1);
+     QCOMPARE(m_dirLister.spyClearKUrl.count(), 0);
+-    QCOMPARE(m_dirLister.spyItemsDeleted.count(), 1);
+-    QCOMPARE(m_dirLister.spyItemsDeleted[0][0].value<KFileItemList>().count(), 1);
++    KUrl::List deletedUrls;
++    for (int i = 0; i < m_dirLister.spyItemsDeleted.count(); ++i)
++        deletedUrls += m_dirLister.spyItemsDeleted[i][0].value<KFileItemList>().urlList();
++    //kDebug() << deletedUrls;
++    KUrl currentDirUrl = QUrl::fromLocalFile(path());
++    currentDirUrl.adjustPath(KUrl::RemoveTrailingSlash);
++    // Sometimes I get ("current/subdir", "current") here, but that seems ok.
++    QVERIFY(deletedUrls.contains(currentDirUrl));
+ }
+ 
+ int KDirListerTest::fileCount() const
+diff --git a/kio/tests/kdirlistertest.h b/kio/tests/kdirlistertest.h
+index a781aca..2fa863c 100644
+--- a/kio/tests/kdirlistertest.h
++++ b/kio/tests/kdirlistertest.h
+@@ -106,6 +106,7 @@ private Q_SLOTS:
+     void testOpenUrlTwice();
+     void testOpenUrlTwiceWithKeep();
+     void testOpenAndStop();
++    void testBug211472();
+     void testRedirection();
+     void testDeleteCurrentDir(); // must be last!
+ 
+-- 
+1.7.10.4
+

-- 
KDE Development Platform Libraries module packaging



More information about the pkg-kde-commits mailing list