From a2668f30e652e0f3b33afad3c7b07e39f82dc506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Wed, 29 Jun 2011 03:32:38 +0200 Subject: [PATCH 2/2] network: fix overlapping request crash in network cache logic Fixes crash when creating a cache-invalidating request on QNetworkAccessManager while another request with the same URL is already in progress. http://bugreports.qt.nokia.com/browse/QTBUG-20162 --- src/network/access/qabstractnetworkcache.h | 3 +++ src/network/access/qnetworkdiskcache.cpp | 4 +++- src/network/access/qnetworkreplyimpl.cpp | 18 ++++++++++++++++++ src/network/access/qnetworkreplyimpl_p.h | 2 ++ 4 files changed, 26 insertions(+), 1 deletions(-) diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h index 3fff74c..51093ba 100644 --- a/src/network/access/qabstractnetworkcache.h +++ b/src/network/access/qabstractnetworkcache.h @@ -125,6 +125,9 @@ public: public Q_SLOTS: virtual void clear() = 0; +Q_SIGNALS: + void deviceDestroyed(QIODevice *device); + protected: explicit QAbstractNetworkCache(QObject *parent = 0); QAbstractNetworkCache(QAbstractNetworkCachePrivate &dd, QObject *parent); diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 3b18fe8..c078e51 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -301,8 +301,10 @@ bool QNetworkDiskCache::remove(const QUrl &url) it.next(); QCacheItem *item = it.value(); if (item && item->metaData.url() == url) { + QIODevice *device = it.key(); + emit deviceDestroyed(device); delete item; - d->inserting.remove(it.key()); + d->inserting.remove(device); return true; } } diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 574b6e9..7d1a733 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -195,6 +195,19 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingDataFinished() QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); } +void QNetworkReplyImplPrivate::_q_cacheDeviceDestroyed(QIODevice *device) +{ + if (device == cacheSaveDevice) { + Q_Q(QNetworkReplyImpl); + + QObject::disconnect(networkCache(), SIGNAL(deviceDestroyed(QIODevice *)), + q, SLOT(_q_cacheDeviceDestroyed(QIODevice *))); + + cacheSaveDevice = 0; + cacheEnabled = false; + } +} + void QNetworkReplyImplPrivate::_q_bufferOutgoingData() { Q_Q(QNetworkReplyImpl); @@ -537,6 +550,11 @@ void QNetworkReplyImplPrivate::initCacheSaveDevice() cacheSaveDevice = 0; cacheEnabled = false; } + + if (cacheSaveDevice) { + QObject::connect(networkCache(), SIGNAL(deviceDestroyed(QIODevice *)), + q, SLOT(_q_cacheDeviceDestroyed(QIODevice *))); + } } // we received downstream data and send this to the cache diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 31da297..e3aee86 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -99,6 +99,7 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_cacheDeviceDestroyed(QIODevice *device)) #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) @@ -135,6 +136,7 @@ public: void _q_copyReadChannelFinished(); void _q_bufferOutgoingData(); void _q_bufferOutgoingDataFinished(); + void _q_cacheDeviceDestroyed(QIODevice *device); #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); -- 1.7.3.4