commit 979b0436510e7807c054e79c40c3753834ac2863 Author: Sebastian Trueg Date: Thu Mar 15 09:14:35 2012 +0100 Thread-safe ResourceWatcher handling. We simply perform all RW operations in the manager thread. BUG: 295474 FIXED-IN: 4.8.2 diff --git a/nepomuk/core/resourcedata.cpp b/nepomuk/core/resourcedata.cpp index abe55ea..9d45228 100644 --- a/nepomuk/core/resourcedata.cpp +++ b/nepomuk/core/resourcedata.cpp @@ -175,7 +175,8 @@ void Nepomuk::ResourceData::resetAll( bool isDelete ) if( !m_uri.isEmpty() ) { m_rm->m_initializedData.remove( m_uri ); if( m_rm->m_watcher && m_addedToWatcher ) { - m_rm->m_watcher->removeResource(Resource::fromResourceUri(m_uri)); + // See load() for an explanation of the QMetaObject call + QMetaObject::invokeMethod(m_rm->m_watcher, "removeResource", Qt::AutoConnection, Q_ARG(Nepomuk::Resource, Resource::fromResourceUri(m_uri))); m_addedToWatcher = false; } } @@ -393,16 +394,23 @@ bool Nepomuk::ResourceData::load() m_cache.clear(); if(!m_rm->m_watcher) { + // + // The ResourceWatcher is not thread-safe. Thus, we need to ensure the safety ourselves. + // We do that by simply handling all RW related operations in the manager thread. + // This also means to invoke methods on the watcher through QMetaObject to make sure they + // get queued in case of calls between different threads. + // m_rm->m_watcher = new ResourceWatcher(m_rm->m_manager); + m_rm->m_watcher->moveToThread(m_rm->m_manager->thread()); QObject::connect( m_rm->m_watcher, SIGNAL(propertyAdded(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)), m_rm->m_manager, SLOT(slotPropertyAdded(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)) ); QObject::connect( m_rm->m_watcher, SIGNAL(propertyRemoved(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)), m_rm->m_manager, SLOT(slotPropertyRemoved(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)) ); m_rm->m_watcher->addResource( Nepomuk::Resource::fromResourceUri(m_uri) ); - m_rm->m_watcher->start(); + QMetaObject::invokeMethod(m_rm->m_watcher, "start", Qt::AutoConnection); } else { - m_rm->m_watcher->addResource( Nepomuk::Resource::fromResourceUri(m_uri) ); + QMetaObject::invokeMethod(m_rm->m_watcher, "addResource", Qt::AutoConnection, Q_ARG(Nepomuk::Resource, Nepomuk::Resource::fromResourceUri(m_uri)) ); } m_addedToWatcher = true; diff --git a/nepomuk/core/resourcewatcher.h b/nepomuk/core/resourcewatcher.h index 06b9622..92b12f5 100644 --- a/nepomuk/core/resourcewatcher.h +++ b/nepomuk/core/resourcewatcher.h @@ -93,6 +93,7 @@ namespace Nepomuk { */ virtual ~ResourceWatcher(); + public Q_SLOTS: /** * \brief Add a type to be watched. * @@ -204,7 +205,6 @@ namespace Nepomuk { */ QList properties() const; - public Q_SLOTS: /** * \brief Start the signalling of changes. *