Commit 243ea615 authored by Dan Leinir Turthra Jensen's avatar Dan Leinir Turthra Jensen 🌈
Browse files

Add a dptr to Cache, and move the throttle timer there to fix crash

Previously, the throttle timer was a raw static, but it was also a parented qobject, which means that when the cache was deleted, so was the timer, but the variable was not reset. Consequently, things would crash left and right later on. So, to alleviate this, and hopefully avoid future issues, introduce a dptr, stick the timer there, and move the logic to that private class as well.

BUG:429442

FIXED-IN:5.78
parent c6b7cd0a
......@@ -11,17 +11,42 @@
#include <QDir>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QPointer>
#include <QTimer>
#include <QXmlStreamReader>
#include <qstandardpaths.h>
#include <knewstuffcore_debug.h>
class KNSCore::CachePrivate {
public:
CachePrivate(Cache* qq)
: q(qq)
{}
~CachePrivate() {}
Cache* q;
QHash<QString, EntryInternal::List> requestCache;
QPointer<QTimer> throttleTimer;
void throttleWrite() {
if (!throttleTimer) {
throttleTimer = new QTimer(q);
QObject::connect(throttleTimer, &QTimer::timeout, q, [this](){ q->writeRegistry(); });
throttleTimer->setSingleShot(true);
throttleTimer->setInterval(1000);
}
throttleTimer->start();
}
};
using namespace KNSCore;
typedef QHash<QString, QWeakPointer<Cache> > CacheHash;
Q_GLOBAL_STATIC(CacheHash, s_caches)
Cache::Cache(const QString &appName): QObject(nullptr)
Cache::Cache(const QString &appName)
: QObject(nullptr)
, d(new CachePrivate(this))
{
m_kns2ComponentName = appName;
......@@ -280,36 +305,30 @@ void Cache::registerChangedEntry(const KNSCore::EntryInternal &entry)
if (entry.status() == KNS3::Entry::Updating || entry.status() == KNS3::Entry::Installing) {
return;
}
static QTimer* writeThrottle{nullptr};
if (!writeThrottle) {
writeThrottle = new QTimer(this);
connect(writeThrottle, &QTimer::timeout, this, [this](){ writeRegistry(); });
writeThrottle->setInterval(1000);
}
if (!property("reloadingRegistry").toBool()) {
setProperty("dirty", true);
cache.remove(entry); // If value already exists in the set, the set is left unchanged
cache.insert(entry);
writeThrottle->start();
d->throttleWrite();
}
}
void Cache::insertRequest(const KNSCore::Provider::SearchRequest &request, const KNSCore::EntryInternal::List &entries)
{
// append new entries
auto &cacheList = requestCache[request.hashForRequest()];
auto &cacheList = d->requestCache[request.hashForRequest()];
for (const auto &entry : entries) {
if (!cacheList.contains(entry)) {
cacheList.append(entry);
}
}
qCDebug(KNEWSTUFFCORE) << request.hashForRequest() << " add: " << entries.size() << " keys: " << requestCache.keys();
qCDebug(KNEWSTUFFCORE) << request.hashForRequest() << " add: " << entries.size() << " keys: " << d->requestCache.keys();
}
EntryInternal::List Cache::requestFromCache(const KNSCore::Provider::SearchRequest &request)
{
qCDebug(KNEWSTUFFCORE) << request.hashForRequest();
return requestCache.value(request.hashForRequest());
return d->requestCache.value(request.hashForRequest());
}
void KNSCore::Cache::removeDeletedEntries()
......
......@@ -16,9 +16,11 @@
#include "knewstuffcore_export.h"
#include <memory.h>
namespace KNSCore
{
class CachePrivate;
class KNEWSTUFFCORE_EXPORT Cache : public QObject
{
Q_OBJECT
......@@ -99,7 +101,8 @@ private:
QString m_kns2ComponentName;
QSet<EntryInternal> cache;
QHash<QString, EntryInternal::List> requestCache;
std::unique_ptr<CachePrivate> d;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment