diff options
author | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-02-01 03:25:03 (GMT) |
---|---|---|
committer | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-02-03 06:58:32 (GMT) |
commit | 72f9a360c5f378092884654257266b4569932336 (patch) | |
tree | 71d3ca7d7a29d9bfbddd95d853836c53da4b8a78 | |
parent | 75a0b3e5526b0a6cf01deb60f0dc37b61928206a (diff) | |
download | Qt-72f9a360c5f378092884654257266b4569932336.zip Qt-72f9a360c5f378092884654257266b4569932336.tar.gz Qt-72f9a360c5f378092884654257266b4569932336.tar.bz2 |
Progress.
-rw-r--r-- | src/network/access/qnetworkaccessbackend.cpp | 43 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessbackend_p.h | 6 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 71 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 40 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl_p.h | 3 |
5 files changed, 109 insertions, 54 deletions
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index d9bce9d..f35cb59 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -342,7 +342,12 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors) #endif } -void QNetworkAccessBackend::start() +/*! + Starts the backend. Returns true if the backend is started. Returns false if the backend + could not be started due to an unopened or roaming session. The caller should recall this + function once the session has been opened or the roaming process has finished. +*/ +bool QNetworkAccessBackend::start() { QHostInfo hostInfo = QHostInfo::fromName(reply->url.host()); foreach (const QHostAddress &address, hostInfo.addresses()) { @@ -350,35 +355,23 @@ void QNetworkAccessBackend::start() address == QHostAddress::LocalHostIPv6) { // Don't need session for local host access. open(); - return; + return true; } } - connect(manager->session, SIGNAL(stateChanged(QNetworkSession::State)), - this, SLOT(sessionStateChanged(QNetworkSession::State))); - connect(manager->session, SIGNAL(error(QNetworkSession::SessionError)), - this, SLOT(sessionError(QNetworkSession::SessionError))); - - switch (manager->session->state()) { - case QNetworkSession::Roaming: - break; - case QNetworkSession::Connected: - open(); - break; - default: - manager->session->open(); + if (manager->session->isOpen()) { + if (manager->session->state() == QNetworkSession::Connected) { + qDebug() << "Session is open and state is connected"; + open(); + return true; + } else { + qDebug() << "we are roaming, connecting, etc. delay until roaming completes"; + } + } else { + qDebug() << "session not open"; } -} -void QNetworkAccessBackend::sessionStateChanged(QNetworkSession::State state) -{ - if (state == QNetworkSession::Connected) - open(); -} - -void QNetworkAccessBackend::sessionError(QNetworkSession::SessionError error) -{ - manager->sendDebugMessage(QString::fromLatin1("Session error %1").arg(error)); + return false; } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 7b7821e..b8b369f 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -112,7 +112,7 @@ public: // socket). virtual void open() = 0; - virtual void start(); + virtual bool start(); virtual void closeDownstreamChannel() = 0; virtual bool waitForDownstreamReadyRead(int msecs) = 0; @@ -188,10 +188,6 @@ protected slots: void sslErrors(const QList<QSslError> &errors); void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); -private slots: - void sessionStateChanged(QNetworkSession::State state); - void sessionError(QNetworkSession::SessionError error); - private: friend class QNetworkAccessManager; friend class QNetworkAccessManagerPrivate; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 3f8ef01..a7a81f8 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -807,13 +807,24 @@ void QNetworkAccessManagerPrivate::_q_replyFinished() if (deferredMigration) { bool repliesPending = false; foreach (QObject *child, q->children()) { - if (child != reply && child->inherits("QNetworkReply")) { - repliesPending = true; - break; + if (child != reply && child->inherits("QNetworkReplyImpl")) { + QNetworkReplyImpl *replyImpl = qobject_cast<QNetworkReplyImpl *>(child); + qDebug() << "reply state is" << replyImpl->d_func()->state; + switch (replyImpl->d_func()->state) { + case QNetworkReplyImplPrivate::Idle: + case QNetworkReplyImplPrivate::Finished: + case QNetworkReplyImplPrivate::Aborted: + break; + case QNetworkReplyImplPrivate::Buffering: + case QNetworkReplyImplPrivate::Working: + repliesPending = true; + break; + } } } if (!repliesPending) { - emit q->debugMessage(QLatin1String("Migrating as there are no pending replies.")); + deferredMigration = false; + qDebug() << "Migrating as there are no pending replies."; session->migrate(); } } @@ -1072,6 +1083,15 @@ QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate() void QNetworkAccessManagerPrivate::_q_sessionOpened() { Q_Q(QNetworkAccessManager); + + qDebug() << "Session Opened"; + + // start waiting children + foreach (QObject *child, q->children()) { + QNetworkReplyImpl *reply = qobject_cast<QNetworkReplyImpl *>(child); + if (reply && reply->d_func()->state == QNetworkReplyImplPrivate::WaitingForSession) + QMetaObject::invokeMethod(reply, "_q_startOperation", Qt::QueuedConnection); + } } void QNetworkAccessManagerPrivate::_q_sessionClosed() @@ -1091,6 +1111,8 @@ void QNetworkAccessManagerPrivate::_q_sessionError(QNetworkSession::SessionError void QNetworkAccessManagerPrivate::_q_sessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); + + qDebug() << "session state changed to" << state; } void QNetworkAccessManagerPrivate::_q_sessionNewConfigurationActivated() @@ -1098,13 +1120,30 @@ void QNetworkAccessManagerPrivate::_q_sessionNewConfigurationActivated() Q_Q(QNetworkAccessManager); foreach (QObject *child, q->children()) { - QNetworkReply *reply = qobject_cast<QNetworkReply *>(child); + QNetworkReplyImpl *reply = qobject_cast<QNetworkReplyImpl *>(child); if (reply) { - emit q->debugMessage(QString::fromLatin1("Unexpected reply for %1").arg(reply->url().toString())); + switch (reply->d_func()->state) { + case QNetworkReplyImplPrivate::Buffering: + case QNetworkReplyImplPrivate::Working: + emit q->debugMessage(QString::fromLatin1("Unexpected reply for %1") + .arg(reply->url().toString())); + break; + default: + qDebug() << "Testing new interface for" << reply->url(); + ; + } } } + qDebug() << "Accepting new configuration."; session->accept(); + + // start waiting children + foreach (QObject *child, q->children()) { + QNetworkReplyImpl *reply = qobject_cast<QNetworkReplyImpl *>(child); + if (reply && reply->d_func()->state == QNetworkReplyImplPrivate::WaitingForSession) + QMetaObject::invokeMethod(reply, "_q_startOperation", Qt::QueuedConnection); + } } void QNetworkAccessManagerPrivate::_q_sessionPreferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless) @@ -1113,14 +1152,26 @@ void QNetworkAccessManagerPrivate::_q_sessionPreferredConfigurationChanged(const deferredMigration = false; foreach (QObject *child, q->children()) { - if (child->inherits("QNetworkReply")) { - deferredMigration = true; - break; + if (child->inherits("QNetworkReplyImpl")) { + QNetworkReplyImpl *replyImpl = qobject_cast<QNetworkReplyImpl *>(child); + qDebug() << "reply state is" << replyImpl->d_func()->state; + switch (replyImpl->d_func()->state) { + case QNetworkReplyImplPrivate::Idle: + case QNetworkReplyImplPrivate::Finished: + case QNetworkReplyImplPrivate::Aborted: + break; + case QNetworkReplyImplPrivate::Buffering: + case QNetworkReplyImplPrivate::Working: + deferredMigration = true; + break; + } } } - if (!deferredMigration) + if (!deferredMigration) { + qDebug() << "Migrating as there are no pending replies."; session->migrate(); + } } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 7eca323..5d52913 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -83,7 +83,18 @@ void QNetworkReplyImplPrivate::_q_startOperation() return; } - backend->start(); + if (!backend->start()) { + // backend failed to start because the session state is not Connected. + // QNetworkAccessManager will call reply->backend->start() again for us when the session + // state changes. + qDebug() << "Waiting for session for" << url; + state = WaitingForSession; + + if (!manager->d_func()->session->isOpen()) + manager->d_func()->session->open(); + + return; + } //backend->open(); if (state != Finished) { @@ -504,20 +515,10 @@ void QNetworkReplyImplPrivate::finished() if (state == Finished || state == Aborted) return; - state = Finished; - pendingNotifications.clear(); - pauseNotificationHandling(); QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); - if (totalSize.isNull() || totalSize == -1) { - emit q->downloadProgress(bytesDownloaded, bytesDownloaded); - } - - if (bytesUploaded == -1 && (outgoingData || outgoingDataBuffer)) - emit q->uploadProgress(0, 0); - resumeNotificationHandling(); - - if (manager->d_func()->session->state() == QNetworkSession::Roaming) { + if (state == Working && errorCode != QNetworkReply::OperationCanceledError && + manager->d_func()->session->state() == QNetworkSession::Roaming) { // only content with a known size will fail with a temporary network failure error if (!totalSize.isNull()) { qDebug() << "Connection broke during download."; @@ -538,6 +539,19 @@ void QNetworkReplyImplPrivate::finished() } } } + resumeNotificationHandling(); + + state = Finished; + pendingNotifications.clear(); + + pauseNotificationHandling(); + if (totalSize.isNull() || totalSize == -1) { + emit q->downloadProgress(bytesDownloaded, bytesDownloaded); + } + + if (bytesUploaded == -1 && (outgoingData || outgoingDataBuffer)) + emit q->uploadProgress(0, 0); + resumeNotificationHandling(); // if we don't know the total size of or we received everything save the cache if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize) diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 168e5cf..861b2b2 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -114,7 +114,8 @@ public: Buffering, Working, Finished, - Aborted + Aborted, + WaitingForSession }; typedef QQueue<InternalNotifications> NotificationQueue; |