Changeset View
Changeset View
Standalone View
Standalone View
src/core/kprotocolinfofactory.cpp
Show All 31 Lines | |||||
32 | Q_GLOBAL_STATIC(KProtocolInfoFactory, kProtocolInfoFactoryInstance) | 32 | Q_GLOBAL_STATIC(KProtocolInfoFactory, kProtocolInfoFactoryInstance) | ||
33 | 33 | | |||
34 | KProtocolInfoFactory *KProtocolInfoFactory::self() | 34 | KProtocolInfoFactory *KProtocolInfoFactory::self() | ||
35 | { | 35 | { | ||
36 | return kProtocolInfoFactoryInstance(); | 36 | return kProtocolInfoFactoryInstance(); | ||
37 | } | 37 | } | ||
38 | 38 | | |||
39 | KProtocolInfoFactory::KProtocolInfoFactory() | 39 | KProtocolInfoFactory::KProtocolInfoFactory() | ||
40 | : m_allProtocolsLoaded(false) | 40 | : m_cacheDirty(true) | ||
41 | { | 41 | { | ||
42 | } | 42 | } | ||
43 | 43 | | |||
44 | KProtocolInfoFactory::~KProtocolInfoFactory() | 44 | KProtocolInfoFactory::~KProtocolInfoFactory() | ||
45 | { | 45 | { | ||
46 | QMutexLocker locker(&m_mutex); | 46 | QMutexLocker locker(&m_mutex); | ||
47 | qDeleteAll(m_cache); | 47 | qDeleteAll(m_cache); | ||
48 | m_cache.clear(); | 48 | m_cache.clear(); | ||
49 | m_allProtocolsLoaded = false; | 49 | m_cacheDirty = true; | ||
50 | } | 50 | } | ||
51 | 51 | | |||
52 | QStringList KProtocolInfoFactory::protocols() | 52 | QStringList KProtocolInfoFactory::protocols() | ||
53 | { | 53 | { | ||
54 | QMutexLocker locker(&m_mutex); | 54 | QMutexLocker locker(&m_mutex); | ||
55 | 55 | | |||
56 | // fill cache, if not already done and use it | 56 | // fill cache, if not already done and use it | ||
57 | fillCache(); | 57 | fillCache(); | ||
58 | return m_cache.keys(); | 58 | return m_cache.keys(); | ||
59 | } | 59 | } | ||
60 | 60 | | |||
61 | QList<KProtocolInfoPrivate *> KProtocolInfoFactory::allProtocols() | 61 | QList<KProtocolInfoPrivate *> KProtocolInfoFactory::allProtocols() | ||
62 | { | 62 | { | ||
63 | QMutexLocker locker(&m_mutex); | 63 | QMutexLocker locker(&m_mutex); | ||
64 | 64 | | |||
65 | // fill cache, if not already done and use it | 65 | // fill cache, if not already done and use it | ||
66 | fillCache(); | 66 | fillCache(); | ||
67 | return m_cache.values(); | 67 | return m_cache.values(); | ||
68 | } | 68 | } | ||
69 | 69 | | |||
70 | KProtocolInfoPrivate *KProtocolInfoFactory::findProtocol(const QString &protocol) | 70 | KProtocolInfoPrivate *KProtocolInfoFactory::findProtocol(const QString &protocol) | ||
71 | { | 71 | { | ||
72 | QMutexLocker locker(&m_mutex); | 72 | QMutexLocker locker(&m_mutex); | ||
73 | 73 | | |||
74 | // fill cache, if not already done and use it | 74 | const bool filled = fillCache(); | ||
75 | fillCache(); | 75 | | ||
76 | KProtocolInfoPrivate *info = m_cache.value(protocol); | 76 | KProtocolInfoPrivate *info = m_cache.value(protocol); | ||
77 | if (!info) { | 77 | if (!info && !filled) { | ||
78 | // Unknown protocol! Maybe it just got installed and our cache is out of date? | 78 | // Unknown protocol! Maybe it just got installed and our cache is out of date? | ||
79 | qCDebug(KIO_CORE) << "Refilling KProtocolInfoFactory cache in the hope to find" << protocol; | 79 | qCDebug(KIO_CORE) << "Refilling KProtocolInfoFactory cache in the hope to find" << protocol; | ||
80 | m_allProtocolsLoaded = false; | 80 | m_cacheDirty = true; | ||
81 | qDeleteAll(m_cache); | | |||
82 | m_cache.clear(); | | |||
83 | fillCache(); | 81 | fillCache(); | ||
84 | info = m_cache.value(protocol); | 82 | info = m_cache.value(protocol); | ||
85 | } | 83 | } | ||
86 | return info; | 84 | return info; | ||
87 | } | 85 | } | ||
88 | 86 | | |||
89 | void KProtocolInfoFactory::fillCache() | 87 | bool KProtocolInfoFactory::fillCache() | ||
90 | { | 88 | { | ||
91 | // mutex MUST be locked from the outside! | 89 | // mutex MUST be locked from the outside! | ||
92 | Q_ASSERT(!m_mutex.tryLock()); | 90 | Q_ASSERT(!m_mutex.tryLock()); | ||
93 | 91 | | |||
94 | // no work if filled | 92 | // no work if filled | ||
95 | if (m_allProtocolsLoaded) { | 93 | if (!m_cacheDirty) { | ||
96 | return; | 94 | return false; | ||
97 | } | 95 | } | ||
98 | 96 | | |||
97 | qDeleteAll(m_cache); | ||||
98 | m_cache.clear(); | ||||
99 | | ||||
99 | // first: search for meta data protocol info, that might be bundled with applications | 100 | // first: search for meta data protocol info, that might be bundled with applications | ||
100 | // we search in all library paths inside kf5/kio | 101 | // we search in all library paths inside kf5/kio | ||
101 | Q_FOREACH (const KPluginMetaData &md, KPluginLoader::findPlugins("kf5/kio")) { | 102 | Q_FOREACH (const KPluginMetaData &md, KPluginLoader::findPlugins("kf5/kio")) { | ||
102 | // get slave name & protocols it supports, if any | 103 | // get slave name & protocols it supports, if any | ||
103 | const QString slavePath = md.fileName(); | 104 | const QString slavePath = md.fileName(); | ||
104 | const QJsonObject protocols(md.rawData().value(QStringLiteral("KDE-KIO-Protocols")).toObject()); | 105 | const QJsonObject protocols(md.rawData().value(QStringLiteral("KDE-KIO-Protocols")).toObject()); | ||
105 | 106 | | |||
106 | // add all protocols, does nothing if object invalid | 107 | // add all protocols, does nothing if object invalid | ||
Show All 22 Lines | 127 | if (file.endsWith(QLatin1String(".protocol"))) { | |||
129 | if (!m_cache.contains(prot)) { | 130 | if (!m_cache.contains(prot)) { | ||
130 | m_cache.insert(prot, new KProtocolInfoPrivate(file)); | 131 | m_cache.insert(prot, new KProtocolInfoPrivate(file)); | ||
131 | } | 132 | } | ||
132 | } | 133 | } | ||
133 | } | 134 | } | ||
134 | } | 135 | } | ||
135 | 136 | | |||
136 | // all done, don't do it again | 137 | // all done, don't do it again | ||
137 | m_allProtocolsLoaded = true; | 138 | m_cacheDirty = false; | ||
139 | return true; | ||||
138 | } | 140 | } |