diff options
author | Markus Goetz <markus@woboq.com> | 2014-09-19 17:18:59 +0200 |
---|---|---|
committer | Markus Goetz <markus@woboq.com> | 2014-09-25 17:10:54 +0200 |
commit | 097b641c3eb588f1707f87e6a9bedb1d3d8cc31d (patch) | |
tree | 4e3fd9d417033e1a742cd2cc03dbd5a4fd214ba2 | |
parent | 5c2d7b1635904da257938af740af024928b8ce5e (diff) |
QNAM: Fix previous HTTP upload CPU fix
My previous fix for CPU load issues between HTTP thread
and user thread was fragile if the upload QIODevice
emitted readyRead() multiple times.
[ChangeLog][QtNetwork][QNetworkAccessManager] Fix behavior of upload QIODevice
that generate data on readyRead() for HTTP PUT/POST
Change-Id: Idb1c2d5a382a704d8cc08fe03c55c883bfc95aa7
Reviewed-by: Christian Kamm <kamm@incasoftware.de>
Reviewed-by: Richard J. Moore <rich@kde.org>
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 11 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl_p.h | 1 | ||||
-rw-r--r-- | tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 2 |
3 files changed, 13 insertions, 1 deletions
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 4efb2f6a2a..511faca11d 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -428,6 +428,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , synchronous(false) , state(Idle) , statusCode(0) + , uploadDeviceChoking(false) , outgoingData(0) , bytesUploaded(-1) , cacheLoadDevice(0) @@ -1291,9 +1292,12 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) char *data = const_cast<char*>(uploadByteDevice->readPointer(maxSize, currentUploadDataLength)); if (currentUploadDataLength == 0) { + uploadDeviceChoking = true; // No bytes from upload byte device. There will be bytes later, it will emit readyRead() // and our uploadByteDeviceReadyReadSlot() is called. return; + } else { + uploadDeviceChoking = false; } // Let's make a copy of this data @@ -1306,7 +1310,12 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) void QNetworkReplyHttpImplPrivate::uploadByteDeviceReadyReadSlot() { // Start the flow between this thread and the HTTP thread again by triggering a upload. - wantUploadDataSlot(1024); + // However only do this when we were choking before, else the state in + // QNonContiguousByteDeviceThreadForwardImpl gets messed up. + if (uploadDeviceChoking) { + uploadDeviceChoking = false; + wantUploadDataSlot(1024); + } } diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index 06a5383ae4..4a5b61a227 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -212,6 +212,7 @@ public: // upload QNonContiguousByteDevice* createUploadByteDevice(); QSharedPointer<QNonContiguousByteDevice> uploadByteDevice; + bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment QIODevice *outgoingData; QSharedPointer<QRingBuffer> outgoingDataBuffer; void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup? diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 70c118b681..85f706fa04 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -7883,6 +7883,8 @@ protected slots: //qDebug() << Q_FUNC_INFO; bandwidthQuota = 8*1024; // fill quota emit readyRead(); + // Emitting readyRead() several times triggers a bug ("QIODevice::read: Called with maxSize < 0") we fix with this commit + emit readyRead(); } }; |