diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-03-09 17:33:17 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-03-10 12:53:35 (GMT) |
commit | 7b34e64198cbcdb8d738c9da11abe08c0ac880ac (patch) | |
tree | 6bea2f03a412ef10803b1bb57e88b4beb0db2b31 | |
parent | f2d8211aa530c6aca65bd52fd4cc57ef74f927c0 (diff) | |
download | Qt-7b34e64198cbcdb8d738c9da11abe08c0ac880ac.zip Qt-7b34e64198cbcdb8d738c9da11abe08c0ac880ac.tar.gz Qt-7b34e64198cbcdb8d738c9da11abe08c0ac880ac.tar.bz2 |
Fix synchronous http deadlock when aborted by internal timeout
QHttpThreadDelegate::abortRequest was deleting itself, but not exiting
the event loop. For the synchronous usage, both these are incorrect.
Without exiting the event loop, the main thread waits forever.
If it deletes itself, then the main thread will access the deleted memory
on return (the delegate->incomingErrorCode class member) which can crash
with frequency depending on heap implementation.
With this change, abort acts more like the synchronousFinishedWithErrorSlot.
Reviewed-by: Markus Goetz
-rw-r--r-- | src/network/access/qhttpthreaddelegate.cpp | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 2cd5979..d75f12c 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -191,6 +191,7 @@ QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) : , downloadBuffer(0) , httpConnection(0) , httpReply(0) + , synchronousRequestLoop(0) { } @@ -316,12 +317,16 @@ void QHttpThreadDelegate::abortRequest() if (httpReply) { delete httpReply; httpReply = 0; - this->deleteLater(); } // Got aborted by the timeout timer - if (synchronous) + if (synchronous) { incomingErrorCode = QNetworkReply::TimeoutError; + QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection); + } else { + //only delete this for asynchronous mode or QNetworkAccessHttpBackend will crash - see QNetworkAccessHttpBackend::postRequest() + this->deleteLater(); + } } void QHttpThreadDelegate::readyReadSlot() |