From 37be55a86f78da6d177e387b79cbc5d2aacef773 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 12 Jul 2011 12:45:02 +0200 Subject: QNAM HTTP: Do zero-copy for small HTTP replies by default Task-Number: QTBUG-19046 Change-Id: I34bf432c81d94787524124b7d110a00305a660c1 Reviewed-on: http://codereview.qt.nokia.com/1516 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Petersson Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnectionchannel.cpp | 15 ++++++++++----- src/network/access/qhttpnetworkreply.cpp | 4 ++-- src/network/access/qnetworkreplyhttpimpl.cpp | 12 ++++++++++-- 3 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index b8ed8ee567..aafdbf7774 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -448,12 +448,17 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() // the buffer in that size. // note that this call will read only from the still buffered data qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress); - bytes += haveRead; - replyPrivate->totalProgress += haveRead; - - // the user will get notified of it via progress signal - if (haveRead > 0) + if (haveRead > 0) { + bytes += haveRead; + replyPrivate->totalProgress += haveRead; + // the user will get notified of it via progress signal emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); + } else if (haveRead == 0) { + // Happens since this called in a loop. Currently no bytes available. + } else if (haveRead < 0) { + connection->d_func()->emitReplyError(socket, reply, QNetworkReply::RemoteHostClosedError); + break; + } } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress && replyPrivate->bodyLength > 0) { // bulk files like images should fulfill these properties and diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 00653b62e8..04bcd06908 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -211,7 +211,7 @@ void QHttpNetworkReply::setDownstreamLimited(bool dsl) bool QHttpNetworkReply::supportsUserProvidedDownloadBuffer() { Q_D(QHttpNetworkReply); - return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0); + return (!d->isChunked() && !d->autoDecompress && d->bodyLength > 0 && d->statusCode == 200); } void QHttpNetworkReply::setUserProvidedDownloadBuffer(char* b) @@ -672,7 +672,7 @@ qint64 QHttpNetworkReplyPrivate::readBodyVeryFast(QAbstractSocket *socket, char qint64 haveRead = 0; haveRead = socket->read(b, bodyLength - contentRead); if (haveRead == -1) { - return 0; // ### error checking here; + return -1; } contentRead += haveRead; diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index df0a32dd6c..52cbaae5e0 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -777,8 +777,16 @@ void QNetworkReplyHttpImplPrivate::postRequest() if (!synchronous) { // Tell our zerocopy policy to the delegate - delegate->downloadBufferMaximumSize = - request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong(); + QVariant downloadBufferMaximumSizeAttribute = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute); + if (downloadBufferMaximumSizeAttribute.isValid()) { + delegate->downloadBufferMaximumSize = downloadBufferMaximumSizeAttribute.toLongLong(); + } else { + // If there is no MaximumDownloadBufferSizeAttribute set (which is for the majority + // of QNetworkRequest) then we can assume we'll do it anyway for small HTTP replies. + // This helps with performance and memory fragmentation. + delegate->downloadBufferMaximumSize = 128*1024; + } + // These atomic integers are used for signal compression delegate->pendingDownloadData = pendingDownloadDataEmissions; -- cgit v1.2.3