diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-02-22 15:40:19 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-02-22 15:53:48 (GMT) |
commit | 7f41f062e05c02ddf31ab6b81444f57904614f2a (patch) | |
tree | 94042c0ae9afc05143f69951e958eaad03463416 /src/network/access | |
parent | b2c41f756e1c0abd3f07a2e7256c3ba1be72832a (diff) | |
download | Qt-7f41f062e05c02ddf31ab6b81444f57904614f2a.zip Qt-7f41f062e05c02ddf31ab6b81444f57904614f2a.tar.gz Qt-7f41f062e05c02ddf31ab6b81444f57904614f2a.tar.bz2 |
Fix duplicate calls to _q_startOperation
Because of the shared QNetworkSession, we need to disconnect the signals
before detaching from the session. Otherwise we may receive signals from
an old session after switching configurations.
Also, when a session is connected, we get both the state change (connected)
and the opened signals from the session. This needs to be distinguished
from the roaming->connected state change to avoid getting the
networkSessionConnected signal twice.
Reviewed-by: Markus Goetz
Task-Number: QTBUG-16901
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 36 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 2 |
3 files changed, 34 insertions, 6 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index f1c4447..00c5d26 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1344,8 +1344,25 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co initializeSession = false; - if (!config.isValid()) { - networkSession.clear(); + QSharedPointer<QNetworkSession> newSession; + if (config.isValid()) + newSession = QSharedNetworkSessionManager::getSession(config); + + if (networkSession) { + //do nothing if new and old session are the same + if (networkSession == newSession) + return; + //disconnect from old session + QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); + QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); + QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + } + + //switch to new session (null if config was invalid) + networkSession = newSession; + + if (!networkSession) { online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible) @@ -1356,8 +1373,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co return; } - networkSession = QSharedNetworkSessionManager::getSession(config); - + //connect to new session QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection); //QueuedConnection is used to avoid deleting the networkSession inside its closed signal QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); @@ -1369,9 +1385,15 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co void QNetworkAccessManagerPrivate::_q_networkSessionClosed() { + Q_Q(QNetworkAccessManager); if (networkSession) { networkConfiguration = networkSession->configuration().identifier(); + //disconnect from old session + QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); + QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); + QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); networkSession.clear(); } } @@ -1380,8 +1402,12 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession { Q_Q(QNetworkAccessManager); - if (state == QNetworkSession::Connected) + //Do not emit the networkSessionConnected signal here, except for roaming -> connected + //transition, otherwise it is emitted twice in a row when opening a connection. + if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming) emit q->networkSessionConnected(); + lastSessionState = state; + if (online) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { online = false; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index cf4d2f3..6dcb6da 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -77,6 +77,7 @@ public: #endif #ifndef QT_NO_BEARERMANAGEMENT networkSession(0), + lastSessionState(QNetworkSession::Invalid), networkAccessible(QNetworkAccessManager::Accessible), online(false), initializeSession(true), @@ -129,6 +130,7 @@ public: #ifndef QT_NO_BEARERMANAGEMENT QSharedPointer<QNetworkSession> networkSession; + QNetworkSession::State lastSessionState; QString networkConfiguration; QNetworkAccessManager::NetworkAccessibility networkAccessible; bool online; diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 41a6c62..8f2e64e 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -74,7 +74,7 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate() void QNetworkReplyImplPrivate::_q_startOperation() { // ensure this function is only being called once - if (state == Working) { + if (state == Working || state == Finished) { qDebug("QNetworkReplyImpl::_q_startOperation was called more than once"); return; } |