From fed4d6d78d6c5d754b40d396e34edd8011afcad7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 13 Mar 2020 12:44:31 +0100 Subject: Fix QNetworkAccessCache after QHash stability semantics change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data structure relies on stable nodes in QHash, something that is not guaranteed in Qt 6 anymore. Change-Id: I9077ed404ee922893099f5eaae76d2dcea414090 Reviewed-by: Tor Arne Vestbø --- src/network/access/qnetworkaccesscache.cpp | 83 +++++++++++++++--------------- src/network/access/qnetworkaccesscache_p.h | 2 +- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/network/access/qnetworkaccesscache.cpp b/src/network/access/qnetworkaccesscache.cpp index ba092f2618..4d65761a0b 100644 --- a/src/network/access/qnetworkaccesscache.cpp +++ b/src/network/access/qnetworkaccesscache.cpp @@ -121,8 +121,9 @@ void QNetworkAccessCache::clear() NodeHash::Iterator it = hashCopy.begin(); NodeHash::Iterator end = hashCopy.end(); for ( ; it != end; ++it) { - it->object->key.clear(); - it->object->dispose(); + (*it)->object->key.clear(); + (*it)->object->dispose(); + delete (*it); } // now delete: @@ -139,11 +140,10 @@ void QNetworkAccessCache::clear() */ void QNetworkAccessCache::linkEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node * const node = hash.value(key); + if (!node) return; - Node *const node = &it.value(); Q_ASSERT(node != oldest && node != newest); Q_ASSERT(node->older == nullptr && node->newer == nullptr); Q_ASSERT(node->useCount == 0); @@ -168,12 +168,10 @@ void QNetworkAccessCache::linkEntry(const QByteArray &key) */ bool QNetworkAccessCache::unlinkEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node * const node = hash.value(key); + if (!node) return false; - Node *const node = &it.value(); - bool wasOldest = false; if (node == oldest) { oldest = node->newer; @@ -230,6 +228,7 @@ void QNetworkAccessCache::timerEvent(QTimerEvent *) oldest->object->dispose(); hash.remove(oldest->key); // oldest gets deleted + delete oldest; oldest = next; } @@ -249,16 +248,20 @@ void QNetworkAccessCache::addEntry(const QByteArray &key, CacheableObject *entry if (unlinkEntry(key)) updateTimer(); - Node &node = hash[key]; // create the entry in the hash if it didn't exist - if (node.useCount) - qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'", - key.constData()); - if (node.object) - node.object->dispose(); - node.object = entry; - node.object->key = key; - node.key = key; - node.useCount = 1; + Node *node = hash.value(key); + if (!node) { + node = new Node; + hash.insert(key, node); + } + + if (node->useCount) + qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'", key.constData()); + if (node->object) + node->object->dispose(); + node->object = entry; + node->object->key = key; + node->key = key; + node->useCount = 1; } bool QNetworkAccessCache::hasEntry(const QByteArray &key) const @@ -268,11 +271,9 @@ bool QNetworkAccessCache::hasEntry(const QByteArray &key) const bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, const char *member) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) - return false; // no such entry - - Node *node = &it.value(); + Node *node = hash.value(key); + if (!node) + return false; if (node->useCount > 0 && !node->object->shareable) { // object is not shareable and is in use @@ -294,13 +295,14 @@ bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, c QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node *node = hash.value(key); + if (!node) return nullptr; - if (it->useCount > 0) { - if (it->object->shareable) { - ++it->useCount; - return it->object; + + if (node->useCount > 0) { + if (node->object->shareable) { + ++node->useCount; + return node->object; } // object in use and not shareable @@ -309,23 +311,21 @@ QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const // entry not in use, let the caller have it bool wasOldest = unlinkEntry(key); - ++it->useCount; + ++node->useCount; if (wasOldest) updateTimer(); - return it->object; + return node->object; } void QNetworkAccessCache::releaseEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) { - qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", - key.constData()); + Node *node = hash.value(key); + if (!node) { + qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", key.constData()); return; } - Node *node = &it.value(); Q_ASSERT(node->useCount > 0); // are there other objects waiting? @@ -356,14 +356,12 @@ void QNetworkAccessCache::releaseEntry(const QByteArray &key) void QNetworkAccessCache::removeEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) { - qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", - key.constData()); + Node *node = hash.value(key); + if (!node) { + qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", key.constData()); return; } - Node *node = &it.value(); if (unlinkEntry(key)) updateTimer(); if (node->useCount > 1) @@ -372,6 +370,7 @@ void QNetworkAccessCache::removeEntry(const QByteArray &key) node->object->key.clear(); hash.remove(node->key); + delete node; } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccesscache_p.h b/src/network/access/qnetworkaccesscache_p.h index 69ea649a8a..9f7001d044 100644 --- a/src/network/access/qnetworkaccesscache_p.h +++ b/src/network/access/qnetworkaccesscache_p.h @@ -71,7 +71,7 @@ class QNetworkAccessCache: public QObject Q_OBJECT public: struct Node; - typedef QHash NodeHash; + typedef QHash NodeHash; class CacheableObject { -- cgit v1.2.3