1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
commit 979b0436510e7807c054e79c40c3753834ac2863
Author: Sebastian Trueg <trueg@kde.org>
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<Types::Property> properties() const;
- public Q_SLOTS:
/**
* \brief Start the signalling of changes.
*
|