diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-01-05 11:07:56 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-02-01 11:33:07 (GMT) |
commit | cdc4ce0acde93b23c7e4941b5c195a8d23ff6900 (patch) | |
tree | 41cfe97dbb6c881b742b41a9a1dfb5a3ac48af15 /src/network/access | |
parent | 54692812331d24939a0263a1625702670503c17a (diff) | |
download | Qt-cdc4ce0acde93b23c7e4941b5c195a8d23ff6900.zip Qt-cdc4ce0acde93b23c7e4941b5c195a8d23ff6900.tar.gz Qt-cdc4ce0acde93b23c7e4941b5c195a8d23ff6900.tar.bz2 |
Workaround crash when multiple QNetworkAccessManager instances are used
Instead of each QNetworkAccessManager owning a QNetworkSession, they now
share a QNetworkSession if they have the same QNetworkConfiguration.
QNetworkAccessManager now uses passive roaming instead of application
level roaming. The state change signal (entering connected state) is used
to indicate reconnection instead of being triggered when sending an ALR
accept().
This preserves the previous behaviour, as QNAM always accepted the
suggested access point from bearer mobility.
In the case of multithreaded applications, one QNetworkSession will be
created for each thread which uses QNetworkAccessManager, as QNetworkSession
is not thread safe.
Task-number: QT-4378
Reviewed-by: Markus Goetz
Reviewed-by: juhvu
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 42 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 6 |
4 files changed, 13 insertions, 39 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index bec217b..94ce3bc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -48,6 +48,7 @@ #include "qabstractnetworkcache.h" #include "QtNetwork/qnetworksession.h" +#include "qsharednetworksession_p.h" #include "qnetworkaccesshttpbackend_p.h" #include "qnetworkaccessftpbackend_p.h" @@ -1343,11 +1344,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co initializeSession = false; - if (networkSession) - delete networkSession; - if (!config.isValid()) { - networkSession = 0; + networkSession.clear(); online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible) @@ -1358,18 +1356,12 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co return; } - networkSession = new QNetworkSession(config, q); + networkSession = QSharedNetworkSessionManager::getSession(config); - QObject::connect(networkSession, SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); - QObject::connect(networkSession, SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); - QObject::connect(networkSession, SIGNAL(stateChanged(QNetworkSession::State)), + QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); + QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); + QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); - QObject::connect(networkSession, SIGNAL(newConfigurationActivated()), - q, SLOT(_q_networkSessionNewConfigurationActivated())); - QObject::connect(networkSession, - SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), - q, - SLOT(_q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool))); _q_networkSessionStateChanged(networkSession->state()); } @@ -1379,32 +1371,16 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() if (networkSession) { networkConfiguration = networkSession->configuration().identifier(); - networkSession->deleteLater(); - networkSession = 0; - } -} - -void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated() -{ - Q_Q(QNetworkAccessManager); - - if (networkSession) { - networkSession->accept(); - - emit q->networkSessionConnected(); + networkSession.clear(); } } -void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool) -{ - if (networkSession) - networkSession->migrate(); -} - void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); + if (state == QNetworkSession::Connected) + emit q->networkSessionConnected(); if (online) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { online = false; diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 95e45f0..9c551a7 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -161,8 +161,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) #if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionNewConfigurationActivated()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool)) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) #endif }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 2c6ee10..cdc4b3d 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -128,7 +128,7 @@ public: #endif #ifndef QT_NO_BEARERMANAGEMENT - QNetworkSession *networkSession; + QSharedPointer<QNetworkSession> networkSession; QString networkConfiguration; QNetworkAccessManager::NetworkAccessibility networkAccessible; bool online; diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 70c318c..373cb22 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -97,7 +97,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() // state changes. state = WaitingForSession; - QNetworkSession *session = manager->d_func()->networkSession; + QNetworkSession *session = manager->d_func()->networkSession.data(); if (session) { Q_Q(QNetworkReplyImpl); @@ -257,7 +257,7 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected() if (manager.isNull()) return; - QNetworkSession *session = manager->d_func()->networkSession; + QNetworkSession *session = manager->d_func()->networkSession.data(); if (!session) return; @@ -693,7 +693,7 @@ void QNetworkReplyImplPrivate::finished() if (!manager.isNull()) { #ifndef QT_NO_BEARERMANAGEMENT - QNetworkSession *session = manager->d_func()->networkSession; + QNetworkSession *session = manager->d_func()->networkSession.data(); if (session && session->state() == QNetworkSession::Roaming && state == Working && errorCode != QNetworkReply::OperationCanceledError) { // only content with a known size will fail with a temporary network failure error |