From cf6a1316df282c3c7e99d952e9fc351498d5f9a4 Mon Sep 17 00:00:00 2001
From: Simeon Bird <bladud@gmail.com>
Date: Mon, 11 Mar 2013 23:38:12 -0400
Subject: [PATCH 1/5] ResourceManager/ResourceWatcher: Make removeResource and
 addResource happen in the ResourceWatcher thread via a QAutoConnection,
 avoiding the thread unsafety of QDBusConnection and thus the crash. Add
 convenience functions to the ResourceWatcher that start and stop it if
 necessary, so that we don't have to jump back and forth between threads.

BUG: 305024
FIXED-IN: 4.10.2
---
 libnepomukcore/datamanagement/resourcewatcher.cpp | 16 ++++++++++++++++
 libnepomukcore/datamanagement/resourcewatcher.h   | 20 ++++++++++++++++++++
 libnepomukcore/resource/resourcemanager.cpp       | 18 ++++--------------
 3 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/libnepomukcore/datamanagement/resourcewatcher.cpp b/libnepomukcore/datamanagement/resourcewatcher.cpp
index f394ae8..d01b8a3 100644
--- a/libnepomukcore/datamanagement/resourcewatcher.cpp
+++ b/libnepomukcore/datamanagement/resourcewatcher.cpp
@@ -169,6 +169,13 @@ void Nepomuk2::ResourceWatcher::addResource(const QUrl& resUri)
     }
 }
 
+void Nepomuk2::ResourceWatcher::addResourceStart(const QUrl& resUri)
+{
+    addResource(resUri);
+    if(resourceCount() <=1){
+        start();
+    }
+}
 
 void Nepomuk2::ResourceWatcher::addType(const Nepomuk2::Types::Class& type)
 {
@@ -199,6 +206,15 @@ void Nepomuk2::ResourceWatcher::removeResource(const QUrl& resUri)
     }
 }
 
+void Nepomuk2::ResourceWatcher::removeResourceStop(const QUrl& resUri)
+{
+    removeResource(resUri);
+    if(!resourceCount()){
+        stop();
+    }
+}
+
+
 void Nepomuk2::ResourceWatcher::removeType(const Nepomuk2::Types::Class& type)
 {
     d->m_types.removeAll(type.uri());
diff --git a/libnepomukcore/datamanagement/resourcewatcher.h b/libnepomukcore/datamanagement/resourcewatcher.h
index 05e3710..909fa0d 100644
--- a/libnepomukcore/datamanagement/resourcewatcher.h
+++ b/libnepomukcore/datamanagement/resourcewatcher.h
@@ -126,6 +126,16 @@ namespace Nepomuk2 {
         void addResource( const QUrl& resUri );
 
         /**
+         * \brief Add a resource to be watched and maybe stop.
+         *
+         * As addResource, but if the added resource is the last first one,
+         * (re)-start the watcher.
+         *
+         * \sa addResource()
+         */
+        void addResourceStart(const QUrl& resUri);
+
+        /**
          * \brief Add a property to be watched.
          *
          * Every change to a value of this property
@@ -165,6 +175,16 @@ namespace Nepomuk2 {
         void removeResource( const QUrl& resUri );
 
         /**
+         * \brief Remove a resource to be watched and maybe stop.
+         *
+         * As removeResource, but if the removed resource is the last one,
+         * stop the watcher.
+         *
+         * \sa removeResource()
+         */
+        void removeResourceStop(const QUrl& resUri);
+
+        /**
          * \brief Remove a property to be watched.
          *
          * Every change to a value of this property
diff --git a/libnepomukcore/resource/resourcemanager.cpp b/libnepomukcore/resource/resourcemanager.cpp
index 2b32be0..03b7b58 100644
--- a/libnepomukcore/resource/resourcemanager.cpp
+++ b/libnepomukcore/resource/resourcemanager.cpp
@@ -423,15 +423,9 @@ void Nepomuk2::ResourceManagerPrivate::addToWatcher( const QUrl& uri )
                           m_manager, SLOT(slotPropertyAdded(Nepomuk2::Resource, Nepomuk2::Types::Property, QVariant)) );
         QObject::connect( m_watcher, SIGNAL(propertyRemoved(Nepomuk2::Resource, Nepomuk2::Types::Property, QVariant)),
                           m_manager, SLOT(slotPropertyRemoved(Nepomuk2::Resource, Nepomuk2::Types::Property, QVariant)) );
-        m_watcher->addResource( uri );
-    }
-    else {
-        QMetaObject::invokeMethod( m_watcher, "addResource", Qt::AutoConnection, Q_ARG(QUrl, uri) );
-    }
-    // (re-)start the watcher in case this resource is the only one in the list of watched
-    if( m_watcher->resourceCount() <= 1 ) {
-        QMetaObject::invokeMethod(m_watcher, "start", Qt::AutoConnection);
     }
+    // add a resource and (re-)start the watcher in case this resource is the only one in the list of watched
+    QMetaObject::invokeMethod( m_watcher, "addResourceStart", Qt::AutoConnection, Q_ARG(QUrl, uri) );
 }
 
 void Nepomuk2::ResourceManagerPrivate::removeFromWatcher( const QUrl& uri )
@@ -439,12 +433,8 @@ void Nepomuk2::ResourceManagerPrivate::removeFromWatcher( const QUrl& uri )
     if( uri.isEmpty() || !m_watcher )
         return;
 
-    m_watcher->removeResource( uri );
-
-    // stop the watcher since we do not want to watch all changes in case there is no ResourceData left
-    if( !m_watcher->resourceCount() ) {
-        QMetaObject::invokeMethod(m_watcher, "stop", Qt::AutoConnection);
-    }
+    // remove a resource and stop the watcher since we do not want to watch all changes in case there is no ResourceData left
+    QMetaObject::invokeMethod( m_watcher, "removeResourceStop", Qt::AutoConnection, Q_ARG(QUrl, uri) );
 }
 
 #include "resourcemanager.moc"
-- 
1.8.2

