summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <ext-shane.2.kearns@nokia.com>2012-05-31 16:09:38 +0100
committerPasi Pentikäinen <ext-pasi.a.pentikainen@nokia.com>2012-06-13 10:11:17 +0200
commit2410bc406d3ff10dee2a955f97eb49a8d25d8264 (patch)
treec746433608db4ea0017a91cb8addcc104bb0782a
parent1aa8368e4a8cf51f8886b281467c8cb4b58b55d2 (diff)
QNAM - maintain a weak reference to the QNetworkSession
When handling signals from the session, a pointer is needed. Also the QNetworkReplyImpl needs to access the manager's session. So, the manager should have a strong and weak reference. The strong reference is held during connection establishment. The weak reference is held all the time, though it will become null when the session is destroyed in idle. The non static member function getNetworkSession() is used to create strong references from the weak reference where required. Task-number: ou1cimx#1004278 Change-Id: I4b5b36b1d996b98e659d993969006c61b4440c15 Reviewed-by: Martin Petersson <Martin.Petersson@nokia.com> (backported from commit bae1613c4c3d8c38b90ed2ba5c1b149e1bc87987) (cherry picked from commit 4d5296d18f3e201daf054d715401a011325e909c) Reviewed-by: Pasi Pentikäinen <ext-pasi.a.pentikainen@nokia.com>
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp11
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp56
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h5
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp6
4 files changed, 48 insertions, 30 deletions
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index 2869232e9a..aad69222bb 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -358,13 +358,14 @@ bool QNetworkAccessBackend::start()
{
#ifndef QT_NO_BEARERMANAGEMENT
// For bearer, check if session start is required
- if (manager->networkSession) {
+ QSharedPointer<QNetworkSession> networkSession(manager->getNetworkSession());
+ if (networkSession) {
// session required
- if (manager->networkSession->isOpen() &&
- manager->networkSession->state() == QNetworkSession::Connected) {
+ if (networkSession->isOpen() &&
+ networkSession->state() == QNetworkSession::Connected) {
// Session is already open and ready to use.
// copy network session down to the backend
- setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
+ setProperty("_q_networksession", QVariant::fromValue(networkSession));
} else {
// Session not ready, but can skip for loopback connections
@@ -387,7 +388,7 @@ bool QNetworkAccessBackend::start()
#ifndef QT_NO_BEARERMANAGEMENT
// Get the proxy settings from the network session (in the case of service networks,
// the proxy settings change depending which AP was activated)
- QNetworkSession *session = manager->networkSession.data();
+ QNetworkSession *session = networkSession.data();
QNetworkConfiguration config;
if (session) {
QNetworkConfigurationManager configManager;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index f2dc1839b6..c4d5e53a88 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -772,8 +772,9 @@ QNetworkConfiguration QNetworkAccessManager::configuration() const
{
Q_D(const QNetworkAccessManager);
- if (d->networkSession)
- return d->networkSession->configuration();
+ QSharedPointer<QNetworkSession> session(d->getNetworkSession());
+ if (session)
+ return session->configuration();
else
return QNetworkConfiguration();
}
@@ -797,11 +798,12 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
{
Q_D(const QNetworkAccessManager);
- if (d->networkSession) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
QNetworkConfigurationManager manager;
return manager.configurationFromIdentifier(
- d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
+ networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
} else {
return QNetworkConfiguration();
}
@@ -836,7 +838,8 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
{
Q_D(const QNetworkAccessManager);
- if (d->networkSession) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
// d->online holds online/offline state of this network session.
if (d->online)
return d->networkAccessible;
@@ -848,6 +851,13 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
}
}
+QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession() const
+{
+ if (networkSessionStrongRef)
+ return networkSessionStrongRef;
+ return networkSessionWeakRef.toStrongRef();
+}
+
#endif // QT_NO_BEARERMANAGEMENT
/*!
@@ -937,7 +947,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
- if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
+ if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
QNetworkConfigurationManager manager;
if (!d->networkConfiguration.isEmpty()) {
d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
@@ -1015,8 +1025,8 @@ void QNetworkAccessManagerPrivate::_q_replyFinished()
// It will not be destroyed immediately, but rather when the connection cache is flushed
// after 2 minutes.
activeReplyCount--;
- if (networkSession && activeReplyCount == 0)
- networkSession.clear();
+ if (networkSessionStrongRef && activeReplyCount == 0)
+ networkSessionStrongRef.clear();
#endif
}
@@ -1176,25 +1186,29 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
initializeSession = false;
+ //resurrect weak ref if possible
+ networkSessionStrongRef = networkSessionWeakRef.toStrongRef();
+
QSharedPointer<QNetworkSession> newSession;
if (config.isValid())
newSession = QSharedNetworkSessionManager::getSession(config);
- if (networkSession) {
+ if (networkSessionStrongRef) {
//do nothing if new and old session are the same
- if (networkSession == newSession)
+ if (networkSessionStrongRef == 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)),
+ QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
+ QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
+ QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
}
//switch to new session (null if config was invalid)
- networkSession = newSession;
+ networkSessionStrongRef = newSession;
+ networkSessionWeakRef = networkSessionStrongRef.toWeakRef();
- if (!networkSession) {
+ if (!networkSessionStrongRef) {
online = false;
if (networkAccessible == QNetworkAccessManager::NotAccessible)
@@ -1206,18 +1220,19 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
}
//connect to new session
- QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
+ QObject::connect(networkSessionStrongRef.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);
- QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
+ QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection);
+ QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
- _q_networkSessionStateChanged(networkSession->state());
+ _q_networkSessionStateChanged(networkSessionStrongRef->state());
}
void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
{
Q_Q(QNetworkAccessManager);
+ QSharedPointer<QNetworkSession> networkSession(getNetworkSession());
if (networkSession) {
networkConfiguration = networkSession->configuration().identifier();
@@ -1226,7 +1241,8 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
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();
+ networkSessionStrongRef.clear();
+ networkSessionWeakRef.clear();
}
}
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index ddacf6857b..8d03c37a58 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -78,7 +78,6 @@ public:
proxyFactory(0),
#endif
#ifndef QT_NO_BEARERMANAGEMENT
- networkSession(0),
lastSessionState(QNetworkSession::Invalid),
networkAccessible(QNetworkAccessManager::Accessible),
activeReplyCount(0),
@@ -113,6 +112,7 @@ public:
#ifndef QT_NO_BEARERMANAGEMENT
void createSession(const QNetworkConfiguration &config);
+ QSharedPointer<QNetworkSession> getNetworkSession() const;
void _q_networkSessionClosed();
void _q_networkSessionNewConfigurationActivated();
@@ -137,7 +137,8 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
- QSharedPointer<QNetworkSession> networkSession;
+ QSharedPointer<QNetworkSession> networkSessionStrongRef;
+ QWeakPointer<QNetworkSession> networkSessionWeakRef;
QNetworkSession::State lastSessionState;
QString networkConfiguration;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 33a56225fe..bf24138700 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.data();
+ QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession());
if (session) {
Q_Q(QNetworkReplyImpl);
@@ -268,7 +268,7 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected()
if (manager.isNull())
return;
- QNetworkSession *session = manager->d_func()->networkSession.data();
+ QSharedPointer<QNetworkSession> session = manager->d_func()->getNetworkSession();
if (!session)
return;
@@ -746,7 +746,7 @@ void QNetworkReplyImplPrivate::finished()
if (!manager.isNull()) {
#ifndef QT_NO_BEARERMANAGEMENT
- QNetworkSession *session = manager->d_func()->networkSession.data();
+ QSharedPointer<QNetworkSession> session (manager->d_func()->getNetworkSession());
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