Fix QNetworkAccessCache after QHash stability semantics change
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ø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
e87768a880
commit
fed4d6d78d
@ -121,8 +121,9 @@ void QNetworkAccessCache::clear()
|
|||||||
NodeHash::Iterator it = hashCopy.begin();
|
NodeHash::Iterator it = hashCopy.begin();
|
||||||
NodeHash::Iterator end = hashCopy.end();
|
NodeHash::Iterator end = hashCopy.end();
|
||||||
for ( ; it != end; ++it) {
|
for ( ; it != end; ++it) {
|
||||||
it->object->key.clear();
|
(*it)->object->key.clear();
|
||||||
it->object->dispose();
|
(*it)->object->dispose();
|
||||||
|
delete (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now delete:
|
// now delete:
|
||||||
@ -139,11 +140,10 @@ void QNetworkAccessCache::clear()
|
|||||||
*/
|
*/
|
||||||
void QNetworkAccessCache::linkEntry(const QByteArray &key)
|
void QNetworkAccessCache::linkEntry(const QByteArray &key)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node * const node = hash.value(key);
|
||||||
if (it == hash.end())
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Node *const node = &it.value();
|
|
||||||
Q_ASSERT(node != oldest && node != newest);
|
Q_ASSERT(node != oldest && node != newest);
|
||||||
Q_ASSERT(node->older == nullptr && node->newer == nullptr);
|
Q_ASSERT(node->older == nullptr && node->newer == nullptr);
|
||||||
Q_ASSERT(node->useCount == 0);
|
Q_ASSERT(node->useCount == 0);
|
||||||
@ -168,12 +168,10 @@ void QNetworkAccessCache::linkEntry(const QByteArray &key)
|
|||||||
*/
|
*/
|
||||||
bool QNetworkAccessCache::unlinkEntry(const QByteArray &key)
|
bool QNetworkAccessCache::unlinkEntry(const QByteArray &key)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node * const node = hash.value(key);
|
||||||
if (it == hash.end())
|
if (!node)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Node *const node = &it.value();
|
|
||||||
|
|
||||||
bool wasOldest = false;
|
bool wasOldest = false;
|
||||||
if (node == oldest) {
|
if (node == oldest) {
|
||||||
oldest = node->newer;
|
oldest = node->newer;
|
||||||
@ -230,6 +228,7 @@ void QNetworkAccessCache::timerEvent(QTimerEvent *)
|
|||||||
oldest->object->dispose();
|
oldest->object->dispose();
|
||||||
|
|
||||||
hash.remove(oldest->key); // oldest gets deleted
|
hash.remove(oldest->key); // oldest gets deleted
|
||||||
|
delete oldest;
|
||||||
oldest = next;
|
oldest = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,16 +248,20 @@ void QNetworkAccessCache::addEntry(const QByteArray &key, CacheableObject *entry
|
|||||||
if (unlinkEntry(key))
|
if (unlinkEntry(key))
|
||||||
updateTimer();
|
updateTimer();
|
||||||
|
|
||||||
Node &node = hash[key]; // create the entry in the hash if it didn't exist
|
Node *node = hash.value(key);
|
||||||
if (node.useCount)
|
if (!node) {
|
||||||
qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'",
|
node = new Node;
|
||||||
key.constData());
|
hash.insert(key, node);
|
||||||
if (node.object)
|
}
|
||||||
node.object->dispose();
|
|
||||||
node.object = entry;
|
if (node->useCount)
|
||||||
node.object->key = key;
|
qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'", key.constData());
|
||||||
node.key = key;
|
if (node->object)
|
||||||
node.useCount = 1;
|
node->object->dispose();
|
||||||
|
node->object = entry;
|
||||||
|
node->object->key = key;
|
||||||
|
node->key = key;
|
||||||
|
node->useCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QNetworkAccessCache::hasEntry(const QByteArray &key) const
|
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)
|
bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, const char *member)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node *node = hash.value(key);
|
||||||
if (it == hash.end())
|
if (!node)
|
||||||
return false; // no such entry
|
return false;
|
||||||
|
|
||||||
Node *node = &it.value();
|
|
||||||
|
|
||||||
if (node->useCount > 0 && !node->object->shareable) {
|
if (node->useCount > 0 && !node->object->shareable) {
|
||||||
// object is not shareable and is in use
|
// 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)
|
QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const QByteArray &key)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node *node = hash.value(key);
|
||||||
if (it == hash.end())
|
if (!node)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (it->useCount > 0) {
|
|
||||||
if (it->object->shareable) {
|
if (node->useCount > 0) {
|
||||||
++it->useCount;
|
if (node->object->shareable) {
|
||||||
return it->object;
|
++node->useCount;
|
||||||
|
return node->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
// object in use and not shareable
|
// object in use and not shareable
|
||||||
@ -309,23 +311,21 @@ QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const
|
|||||||
|
|
||||||
// entry not in use, let the caller have it
|
// entry not in use, let the caller have it
|
||||||
bool wasOldest = unlinkEntry(key);
|
bool wasOldest = unlinkEntry(key);
|
||||||
++it->useCount;
|
++node->useCount;
|
||||||
|
|
||||||
if (wasOldest)
|
if (wasOldest)
|
||||||
updateTimer();
|
updateTimer();
|
||||||
return it->object;
|
return node->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNetworkAccessCache::releaseEntry(const QByteArray &key)
|
void QNetworkAccessCache::releaseEntry(const QByteArray &key)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node *node = hash.value(key);
|
||||||
if (it == hash.end()) {
|
if (!node) {
|
||||||
qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache",
|
qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", key.constData());
|
||||||
key.constData());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *node = &it.value();
|
|
||||||
Q_ASSERT(node->useCount > 0);
|
Q_ASSERT(node->useCount > 0);
|
||||||
|
|
||||||
// are there other objects waiting?
|
// are there other objects waiting?
|
||||||
@ -356,14 +356,12 @@ void QNetworkAccessCache::releaseEntry(const QByteArray &key)
|
|||||||
|
|
||||||
void QNetworkAccessCache::removeEntry(const QByteArray &key)
|
void QNetworkAccessCache::removeEntry(const QByteArray &key)
|
||||||
{
|
{
|
||||||
NodeHash::Iterator it = hash.find(key);
|
Node *node = hash.value(key);
|
||||||
if (it == hash.end()) {
|
if (!node) {
|
||||||
qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache",
|
qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", key.constData());
|
||||||
key.constData());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *node = &it.value();
|
|
||||||
if (unlinkEntry(key))
|
if (unlinkEntry(key))
|
||||||
updateTimer();
|
updateTimer();
|
||||||
if (node->useCount > 1)
|
if (node->useCount > 1)
|
||||||
@ -372,6 +370,7 @@ void QNetworkAccessCache::removeEntry(const QByteArray &key)
|
|||||||
|
|
||||||
node->object->key.clear();
|
node->object->key.clear();
|
||||||
hash.remove(node->key);
|
hash.remove(node->key);
|
||||||
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -71,7 +71,7 @@ class QNetworkAccessCache: public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
struct Node;
|
struct Node;
|
||||||
typedef QHash<QByteArray, Node> NodeHash;
|
typedef QHash<QByteArray, Node *> NodeHash;
|
||||||
|
|
||||||
class CacheableObject
|
class CacheableObject
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user