diff options
author | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-03-05 02:10:19 (GMT) |
---|---|---|
committer | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-03-05 03:34:33 (GMT) |
commit | 92c624b6e26cf950ca651cee59be8ab53ada9a7d (patch) | |
tree | b79048d0af50b5b7304a8c66d0a439164ac2e2c9 /src | |
parent | 445ae84fbd7d5ef04a426f8c32a79a369fed70eb (diff) | |
download | Qt-92c624b6e26cf950ca651cee59be8ab53ada9a7d.zip Qt-92c624b6e26cf950ca651cee59be8ab53ada9a7d.tar.gz Qt-92c624b6e26cf950ca651cee59be8ab53ada9a7d.tar.bz2 |
Don't keep polling network sessions open indefinitely.
Diffstat (limited to 'src')
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 21 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.h | 1 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager_p.h | 2 | ||||
-rw-r--r-- | src/network/bearer/qnetworksession.cpp | 14 | ||||
-rw-r--r-- | src/plugins/bearer/qnetworksession_impl.cpp | 52 | ||||
-rw-r--r-- | src/plugins/bearer/qnetworksession_impl.h | 9 |
6 files changed, 85 insertions, 14 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 5876ee2..7bb1399 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -880,11 +880,16 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera return new QDisabledNetworkReply(this, req, op); } - if (d->initializeSession && !d->networkSession) { + if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) { QNetworkConfigurationManager manager; - d->createSession(manager.defaultConfiguration()); + if (d->networkConfiguration.isEmpty()) + d->createSession(manager.defaultConfiguration()); + else + d->createSession(manager.configurationFromIdentifier(d->networkConfiguration)); d->initializeSession = false; + } else if (d->networkSession) { + d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1); } QNetworkRequest request = req; @@ -943,6 +948,9 @@ void QNetworkAccessManagerPrivate::_q_replyFinished() QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender()); if (reply) emit q->finished(reply); + + if (networkSession && q->findChildren<QNetworkReply *>().count() == 1) + networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), 120000); } void QNetworkAccessManagerPrivate::_q_replySslErrors(const QList<QSslError> &errors) @@ -1210,6 +1218,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co networkSession = new QNetworkSession(config, q); QObject::connect(networkSession, SIGNAL(opened()), q, SIGNAL(networkSessionOnline())); + QObject::connect(networkSession, SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::connect(networkSession, SIGNAL(newConfigurationActivated()), q, SLOT(_q_networkSessionNewConfigurationActivated())); QObject::connect(networkSession, @@ -1218,6 +1227,14 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co SLOT(_q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool))); } +void QNetworkAccessManagerPrivate::_q_networkSessionClosed() +{ + networkConfiguration = networkSession->configuration().identifier(); + + delete networkSession; + networkSession = 0; +} + void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated() { Q_Q(QNetworkAccessManager); diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 252dfd0..694a54f 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -139,6 +139,7 @@ private: Q_DECLARE_PRIVATE(QNetworkAccessManager) Q_PRIVATE_SLOT(d_func(), void _q_replyFinished()) Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) + 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)) }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 8d772f0..0140268 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -105,6 +105,7 @@ public: void createSession(const QNetworkConfiguration &config); + void _q_networkSessionClosed(); void _q_networkSessionNewConfigurationActivated(); void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless); @@ -121,6 +122,7 @@ public: #endif QNetworkSession *networkSession; + QString networkConfiguration; bool networkAccessEnabled; bool initializeSession; diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index f0d7ede..27922af 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -492,6 +492,20 @@ QString QNetworkSession::errorString() const \o Setting this property to \i true before calling \l open() implies that the connection attempt is made but if no connection can be established, the user is not connsulted and asked to select a suitable connection. This property is not set by default and support for it depends on the platform. + + \row + \o AutoCloseSessionTimeout + \o If the session requires polling to keep its state up to date, this property holds + the timeout in milliseconds before the session will automatically close. If the + value of this property is -1 the session will not automatically close. This property + is set to -1 by default. + + The purpose of this property is to minimize resource use on platforms that use + polling to update the state of the session. Applications can set the value of this + property to the desired timeout before the session is closed. In response to the + closed() signal the network session should be deleted to ensure that all polling is + stopped. The session can then be recreated once it is required again. This property + has no effect for sessions that do not require polling. \endtable */ QVariant QNetworkSession::sessionProperty(const QString& key) const diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index 11585ef..0ba1237 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -100,9 +100,6 @@ void QNetworkSessionManagerPrivate::forceSessionClose(const QNetworkConfiguratio void QNetworkSessionPrivateImpl::syncStateWithInterface() { - connect(&manager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationsChanged())); - connect(&manager, SIGNAL(configurationChanged(QNetworkConfiguration)), - this, SLOT(configurationChanged(QNetworkConfiguration))); connect(sessionManager(), SIGNAL(forcedSessionClose(QNetworkConfiguration)), this, SLOT(forcedSessionClose(QNetworkConfiguration))); @@ -119,6 +116,10 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() activeConfig = publicConfig; engine = getEngineFromId(activeConfig.identifier()); if (engine) { + qRegisterMetaType<QNetworkConfigurationPrivatePointer>("QNetworkConfigurationPrivatePointer"); + connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), + this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)), + Qt::QueuedConnection); connect(engine, SIGNAL(connectionError(QString,QBearerEngineImpl::ConnectionError)), this, SLOT(connectionError(QString,QBearerEngineImpl::ConnectionError)), Qt::QueuedConnection); @@ -233,13 +234,37 @@ QNetworkInterface QNetworkSessionPrivateImpl::currentInterface() const return QNetworkInterface::interfaceFromName(interface); } -QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString& /*key*/) const +QVariant QNetworkSessionPrivateImpl::sessionProperty(const QString &key) const { + if (key == QLatin1String("AutoCloseSessionTimeout")) { + if (engine && engine->requiresPolling() && + !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) { + if (sessionTimeout >= 0) + return sessionTimeout * 10000; + else + return -1; + } + } + return QVariant(); } -void QNetworkSessionPrivateImpl::setSessionProperty(const QString& /*key*/, const QVariant& /*value*/) +void QNetworkSessionPrivateImpl::setSessionProperty(const QString &key, const QVariant &value) { + if (key == QLatin1String("AutoCloseSessionTimeout")) { + if (engine && engine->requiresPolling() && + !(engine->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) { + int timeout = value.toInt(); + if (timeout >= 0) { + connect(engine, SIGNAL(updateCompleted()), + this, SLOT(decrementTimeout()), Qt::UniqueConnection); + sessionTimeout = timeout / 10000; // convert to poll intervals + } else { + disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout())); + sessionTimeout = -1; + } + } + } } QString QNetworkSessionPrivateImpl::errorString() const @@ -364,12 +389,14 @@ void QNetworkSessionPrivateImpl::networkConfigurationsChanged() startTime = engine->startTime(activeConfig.identifier()); } -void QNetworkSessionPrivateImpl::configurationChanged(const QNetworkConfiguration &config) +void QNetworkSessionPrivateImpl::configurationChanged(QNetworkConfigurationPrivatePointer config) { - if (serviceConfig.isValid() && (config == serviceConfig || config == activeConfig)) + if (serviceConfig.isValid() && + (config->id == serviceConfig.identifier() || config->id == activeConfig.identifier())) { updateStateFromServiceNetwork(); - else if (config == activeConfig) + } else if (config->id == activeConfig.identifier()) { updateStateFromActiveConfig(); + } } void QNetworkSessionPrivateImpl::forcedSessionClose(const QNetworkConfiguration &config) @@ -406,4 +433,13 @@ void QNetworkSessionPrivateImpl::connectionError(const QString &id, } } +void QNetworkSessionPrivateImpl::decrementTimeout() +{ + if (--sessionTimeout <= 0) { + disconnect(engine, SIGNAL(updateCompleted()), this, SLOT(decrementTimeout())); + sessionTimeout = -1; + close(); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index 7349e77..c644174 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -69,7 +69,7 @@ class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate Q_OBJECT public: QNetworkSessionPrivateImpl() - : startTime(0) + : startTime(0), sessionTimeout(-1) { } @@ -108,13 +108,12 @@ private: private Q_SLOTS: void networkConfigurationsChanged(); - void configurationChanged(const QNetworkConfiguration &config); + void configurationChanged(QNetworkConfigurationPrivatePointer config); void forcedSessionClose(const QNetworkConfiguration &config); void connectionError(const QString &id, QBearerEngineImpl::ConnectionError error); + void decrementTimeout(); private: - QNetworkConfigurationManager manager; - bool opened; QBearerEngineImpl *engine; @@ -122,6 +121,8 @@ private: QNetworkSession::SessionError lastError; quint64 startTime; + + int sessionTimeout; }; QT_END_NAMESPACE |