Skip to content

Commit 2410bc4

Browse files
Shane KearnsPasi Pentikäinen
authored andcommitted
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 <[email protected]> (backported from commit bae1613c4c3d8c38b90ed2ba5c1b149e1bc87987) (cherry picked from commit 4d5296d) Reviewed-by: Pasi Pentikäinen <[email protected]>
1 parent 1aa8368 commit 2410bc4

File tree

4 files changed

+48
-30
lines changed

4 files changed

+48
-30
lines changed

src/network/access/qnetworkaccessbackend.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,14 @@ bool QNetworkAccessBackend::start()
358358
{
359359
#ifndef QT_NO_BEARERMANAGEMENT
360360
// For bearer, check if session start is required
361-
if (manager->networkSession) {
361+
QSharedPointer<QNetworkSession> networkSession(manager->getNetworkSession());
362+
if (networkSession) {
362363
// session required
363-
if (manager->networkSession->isOpen() &&
364-
manager->networkSession->state() == QNetworkSession::Connected) {
364+
if (networkSession->isOpen() &&
365+
networkSession->state() == QNetworkSession::Connected) {
365366
// Session is already open and ready to use.
366367
// copy network session down to the backend
367-
setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
368+
setProperty("_q_networksession", QVariant::fromValue(networkSession));
368369
} else {
369370
// Session not ready, but can skip for loopback connections
370371

@@ -387,7 +388,7 @@ bool QNetworkAccessBackend::start()
387388
#ifndef QT_NO_BEARERMANAGEMENT
388389
// Get the proxy settings from the network session (in the case of service networks,
389390
// the proxy settings change depending which AP was activated)
390-
QNetworkSession *session = manager->networkSession.data();
391+
QNetworkSession *session = networkSession.data();
391392
QNetworkConfiguration config;
392393
if (session) {
393394
QNetworkConfigurationManager configManager;

src/network/access/qnetworkaccessmanager.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,9 @@ QNetworkConfiguration QNetworkAccessManager::configuration() const
772772
{
773773
Q_D(const QNetworkAccessManager);
774774

775-
if (d->networkSession)
776-
return d->networkSession->configuration();
775+
QSharedPointer<QNetworkSession> session(d->getNetworkSession());
776+
if (session)
777+
return session->configuration();
777778
else
778779
return QNetworkConfiguration();
779780
}
@@ -797,11 +798,12 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
797798
{
798799
Q_D(const QNetworkAccessManager);
799800

800-
if (d->networkSession) {
801+
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
802+
if (networkSession) {
801803
QNetworkConfigurationManager manager;
802804

803805
return manager.configurationFromIdentifier(
804-
d->networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
806+
networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
805807
} else {
806808
return QNetworkConfiguration();
807809
}
@@ -836,7 +838,8 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
836838
{
837839
Q_D(const QNetworkAccessManager);
838840

839-
if (d->networkSession) {
841+
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
842+
if (networkSession) {
840843
// d->online holds online/offline state of this network session.
841844
if (d->online)
842845
return d->networkAccessible;
@@ -848,6 +851,13 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
848851
}
849852
}
850853

854+
QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession() const
855+
{
856+
if (networkSessionStrongRef)
857+
return networkSessionStrongRef;
858+
return networkSessionWeakRef.toStrongRef();
859+
}
860+
851861
#endif // QT_NO_BEARERMANAGEMENT
852862

853863
/*!
@@ -937,7 +947,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
937947
return new QDisabledNetworkReply(this, req, op);
938948
}
939949

940-
if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
950+
if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
941951
QNetworkConfigurationManager manager;
942952
if (!d->networkConfiguration.isEmpty()) {
943953
d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
@@ -1015,8 +1025,8 @@ void QNetworkAccessManagerPrivate::_q_replyFinished()
10151025
// It will not be destroyed immediately, but rather when the connection cache is flushed
10161026
// after 2 minutes.
10171027
activeReplyCount--;
1018-
if (networkSession && activeReplyCount == 0)
1019-
networkSession.clear();
1028+
if (networkSessionStrongRef && activeReplyCount == 0)
1029+
networkSessionStrongRef.clear();
10201030
#endif
10211031
}
10221032

@@ -1176,25 +1186,29 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
11761186

11771187
initializeSession = false;
11781188

1189+
//resurrect weak ref if possible
1190+
networkSessionStrongRef = networkSessionWeakRef.toStrongRef();
1191+
11791192
QSharedPointer<QNetworkSession> newSession;
11801193
if (config.isValid())
11811194
newSession = QSharedNetworkSessionManager::getSession(config);
11821195

1183-
if (networkSession) {
1196+
if (networkSessionStrongRef) {
11841197
//do nothing if new and old session are the same
1185-
if (networkSession == newSession)
1198+
if (networkSessionStrongRef == newSession)
11861199
return;
11871200
//disconnect from old session
1188-
QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
1189-
QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
1190-
QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
1201+
QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
1202+
QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
1203+
QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)),
11911204
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
11921205
}
11931206

11941207
//switch to new session (null if config was invalid)
1195-
networkSession = newSession;
1208+
networkSessionStrongRef = newSession;
1209+
networkSessionWeakRef = networkSessionStrongRef.toWeakRef();
11961210

1197-
if (!networkSession) {
1211+
if (!networkSessionStrongRef) {
11981212
online = false;
11991213

12001214
if (networkAccessible == QNetworkAccessManager::NotAccessible)
@@ -1206,18 +1220,19 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
12061220
}
12071221

12081222
//connect to new session
1209-
QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
1223+
QObject::connect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
12101224
//QueuedConnection is used to avoid deleting the networkSession inside its closed signal
1211-
QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection);
1212-
QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
1225+
QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection);
1226+
QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)),
12131227
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
12141228

1215-
_q_networkSessionStateChanged(networkSession->state());
1229+
_q_networkSessionStateChanged(networkSessionStrongRef->state());
12161230
}
12171231

12181232
void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
12191233
{
12201234
Q_Q(QNetworkAccessManager);
1235+
QSharedPointer<QNetworkSession> networkSession(getNetworkSession());
12211236
if (networkSession) {
12221237
networkConfiguration = networkSession->configuration().identifier();
12231238

@@ -1226,7 +1241,8 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
12261241
QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
12271242
QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
12281243
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
1229-
networkSession.clear();
1244+
networkSessionStrongRef.clear();
1245+
networkSessionWeakRef.clear();
12301246
}
12311247
}
12321248

src/network/access/qnetworkaccessmanager_p.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
7878
proxyFactory(0),
7979
#endif
8080
#ifndef QT_NO_BEARERMANAGEMENT
81-
networkSession(0),
8281
lastSessionState(QNetworkSession::Invalid),
8382
networkAccessible(QNetworkAccessManager::Accessible),
8483
activeReplyCount(0),
@@ -113,6 +112,7 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
113112

114113
#ifndef QT_NO_BEARERMANAGEMENT
115114
void createSession(const QNetworkConfiguration &config);
115+
QSharedPointer<QNetworkSession> getNetworkSession() const;
116116

117117
void _q_networkSessionClosed();
118118
void _q_networkSessionNewConfigurationActivated();
@@ -137,7 +137,8 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
137137
#endif
138138

139139
#ifndef QT_NO_BEARERMANAGEMENT
140-
QSharedPointer<QNetworkSession> networkSession;
140+
QSharedPointer<QNetworkSession> networkSessionStrongRef;
141+
QWeakPointer<QNetworkSession> networkSessionWeakRef;
141142
QNetworkSession::State lastSessionState;
142143
QString networkConfiguration;
143144
QNetworkAccessManager::NetworkAccessibility networkAccessible;

src/network/access/qnetworkreplyimpl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
9797
// state changes.
9898
state = WaitingForSession;
9999

100-
QNetworkSession *session = manager->d_func()->networkSession.data();
100+
QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession());
101101

102102
if (session) {
103103
Q_Q(QNetworkReplyImpl);
@@ -268,7 +268,7 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected()
268268
if (manager.isNull())
269269
return;
270270

271-
QNetworkSession *session = manager->d_func()->networkSession.data();
271+
QSharedPointer<QNetworkSession> session = manager->d_func()->getNetworkSession();
272272
if (!session)
273273
return;
274274

@@ -746,7 +746,7 @@ void QNetworkReplyImplPrivate::finished()
746746

747747
if (!manager.isNull()) {
748748
#ifndef QT_NO_BEARERMANAGEMENT
749-
QNetworkSession *session = manager->d_func()->networkSession.data();
749+
QSharedPointer<QNetworkSession> session (manager->d_func()->getNetworkSession());
750750
if (session && session->state() == QNetworkSession::Roaming &&
751751
state == Working && errorCode != QNetworkReply::OperationCanceledError) {
752752
// only content with a known size will fail with a temporary network failure error

0 commit comments

Comments
 (0)