summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp7
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp14
-rw-r--r--tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp18
3 files changed, 33 insertions, 6 deletions
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 4908e0a..120e3a7 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -711,8 +711,13 @@ void QNetworkAccessHttpBackend::replyDownloadData(QByteArray d)
pendingDownloadData.append(d);
d.clear();
- writeDownstreamData(pendingDownloadData);
+ // We need to usa a copy for calling writeDownstreamData as we could
+ // possibly recurse into this this function when we call
+ // appendDownstreamDataSignalEmissions because the user might call
+ // processEvents() or spin an event loop when this occur.
+ QByteDataBuffer pendingDownloadDataCopy = pendingDownloadData;
pendingDownloadData.clear();
+ writeDownstreamData(pendingDownloadDataCopy);
}
void QNetworkAccessHttpBackend::replyFinished()
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 485f449..ce42327 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -178,9 +178,11 @@ void QNetworkReplyImplPrivate::_q_copyReadyRead()
if (preMigrationDownloaded != Q_INT64_C(-1))
totalSize = totalSize.toLongLong() + preMigrationDownloaded;
pauseNotificationHandling();
+ // emit readyRead before downloadProgress incase this will cause events to be
+ // processed and we get into a recursive call (as in QProgressDialog).
+ emit q->readyRead();
emit q->downloadProgress(bytesDownloaded,
totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong());
- emit q->readyRead();
resumeNotificationHandling();
}
@@ -579,11 +581,13 @@ void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions()
if (preMigrationDownloaded != Q_INT64_C(-1))
totalSize = totalSize.toLongLong() + preMigrationDownloaded;
pauseNotificationHandling();
- emit q->downloadProgress(bytesDownloaded,
- totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong());
// important: At the point of this readyRead(), the data parameter list must be empty,
// else implicit sharing will trigger memcpy when the user is reading data!
emit q->readyRead();
+ // emit readyRead before downloadProgress incase this will cause events to be
+ // processed and we get into a recursive call (as in QProgressDialog).
+ emit q->downloadProgress(bytesDownloaded,
+ totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong());
resumeNotificationHandling();
// do we still have room in the buffer?
@@ -684,10 +688,12 @@ void QNetworkReplyImplPrivate::appendDownstreamDataDownloadBuffer(qint64 bytesRe
downloadBufferCurrentSize = bytesReceived;
- emit q->downloadProgress(bytesDownloaded, bytesTotal);
// Only emit readyRead when actual data is there
+ // emit readyRead before downloadProgress incase this will cause events to be
+ // processed and we get into a recursive call (as in QProgressDialog).
if (bytesDownloaded > 0)
emit q->readyRead();
+ emit q->downloadProgress(bytesDownloaded, bytesTotal);
}
void QNetworkReplyImplPrivate::finished()
diff --git a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp
index 42bb069..f7c5ca1 100644
--- a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp
+++ b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp
@@ -58,6 +58,7 @@ public:
tst_QNetworkAccessManager_And_QProgressDialog();
private slots:
void downloadCheck();
+ void downloadCheck_data();
};
class DownloadCheckWidget : public QWidget
@@ -72,9 +73,14 @@ public:
QMetaObject::invokeMethod(this, "go", Qt::QueuedConnection);
}
bool lateReadyRead;
+ bool zeroCopy;
public slots:
void go()
{
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"));
+ if (zeroCopy)
+ request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 10*1024*1024);
+
QNetworkReply *reply = netmanager.get(
QNetworkRequest(
QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile")
@@ -106,20 +112,30 @@ public slots:
QTestEventLoop::instance().exitLoop();
}
-
private:
QProgressDialog progressDlg;
QNetworkAccessManager netmanager;
};
+
tst_QNetworkAccessManager_And_QProgressDialog::tst_QNetworkAccessManager_And_QProgressDialog()
{
Q_SET_DEFAULT_IAP
}
+void tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck_data()
+{
+ QTest::addColumn<bool>("useZeroCopy");
+ QTest::newRow("with-zeroCopy") << true;
+ QTest::newRow("without-zeroCopy") << false;
+}
+
void tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck()
{
+ QFETCH(bool, useZeroCopy);
+
DownloadCheckWidget widget;
+ widget.zeroCopy = useZeroCopy;
widget.show();
// run and exit on finished()
QTestEventLoop::instance().enterLoop(10);