diff options
author | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-03-08 03:04:13 (GMT) |
---|---|---|
committer | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2010-03-11 22:27:21 (GMT) |
commit | cf69144f2b5511c6e4e81bd9da8ee6acd2340e5c (patch) | |
tree | 5df42e812b7c824486cc8ae7f333e99e5b5bd176 /src/network/bearer/qnetworkconfigmanager_p.cpp | |
parent | 0b2190dad38cbe4c8245d500a0fc7cf6f69cc0da (diff) | |
download | Qt-cf69144f2b5511c6e4e81bd9da8ee6acd2340e5c.zip Qt-cf69144f2b5511c6e4e81bd9da8ee6acd2340e5c.tar.gz Qt-cf69144f2b5511c6e4e81bd9da8ee6acd2340e5c.tar.bz2 |
Make QNetworkConfigurationManager and QNetworkConfiguration threadsafe.
Diffstat (limited to 'src/network/bearer/qnetworkconfigmanager_p.cpp')
-rw-r--r-- | src/network/bearer/qnetworkconfigmanager_p.cpp | 218 |
1 files changed, 211 insertions, 7 deletions
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 9740424..c665fa2 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -47,6 +47,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qtimer.h> #include <QtCore/qstringlist.h> +#include <QtCore/qthread.h> #include <QtCore/private/qcoreapplication_p.h> QT_BEGIN_NAMESPACE @@ -57,11 +58,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() : capFlags(0), mutex(QMutex::Recursive), pollTimer(0), forcedPolling(0), firstUpdate(true) { - updateConfigurations(); + qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration"); moveToThread(QCoreApplicationPrivate::mainThread()); - foreach (QBearerEngine *engine, sessionEngines) - engine->moveToThread(QCoreApplicationPrivate::mainThread()); + updateConfigurations(); } QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() @@ -71,6 +71,200 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() qDeleteAll(sessionEngines); } +QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() +{ + QMutexLocker locker(&mutex); + + foreach (QBearerEngine *engine, sessionEngines) { + QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration(); + + if (ptr) { + QNetworkConfiguration config; + config.d = ptr; + return config; + } + } + + // Engines don't have a default configuration. + + // Return first active snap + QNetworkConfigurationPrivatePointer defaultConfiguration; + + foreach (QBearerEngine *engine, sessionEngines) { + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it; + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end; + + QMutexLocker locker(&engine->mutex); + + for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end(); + it != end; ++it) { + QNetworkConfigurationPrivatePointer ptr = it.value(); + + QMutexLocker configLocker(&ptr->mutex); + + if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { + QNetworkConfiguration config; + config.d = ptr; + return config; + } else if (!defaultConfiguration) { + if ((ptr->state & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + defaultConfiguration = ptr; + } + } + } + } + + // No Active SNAPs return first Discovered SNAP. + if (defaultConfiguration) { + QNetworkConfiguration config; + config.d = defaultConfiguration; + return config; + } + + /* + No Active or Discovered SNAPs, find the perferred access point. + The following priority order is used: + + 1. Active Ethernet + 2. Active WLAN + 3. Active Other + 4. Discovered Ethernet + 5. Discovered WLAN + 6. Discovered Other + */ + + defaultConfiguration.reset(); + + foreach (QBearerEngine *engine, sessionEngines) { + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it; + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end; + + QMutexLocker locker(&engine->mutex); + + for (it = engine->accessPointConfigurations.begin(), + end = engine->accessPointConfigurations.end(); it != end; ++it) { + QNetworkConfigurationPrivatePointer ptr = it.value(); + + const QString bearerName = ptr->bearerName(); + QMutexLocker configLocker(&ptr->mutex); + + if ((ptr->state & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { + if (!defaultConfiguration) { + defaultConfiguration = ptr; + } else { + if (defaultConfiguration->state == ptr->state) { + if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) { + // do nothing + } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) { + // ethernet beats wlan + if (bearerName == QLatin1String("Ethernet")) + defaultConfiguration = ptr; + } else { + // ethernet and wlan beats other + if (bearerName == QLatin1String("Ethernet") || + bearerName == QLatin1String("WLAN")) { + defaultConfiguration = ptr; + } + } + } else { + // active beats discovered + if ((defaultConfiguration->state & QNetworkConfiguration::Active) != + QNetworkConfiguration::Active) { + defaultConfiguration = ptr; + } + } + } + } + } + } + + // No Active InternetAccessPoint return first Discovered InternetAccessPoint. + if (defaultConfiguration) { + QNetworkConfiguration config; + config.d = defaultConfiguration; + return config; + } + + return QNetworkConfiguration(); +} + +QList<QNetworkConfiguration> QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) +{ + QList<QNetworkConfiguration> result; + + QMutexLocker locker(&mutex); + + foreach (QBearerEngine *engine, sessionEngines) { + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it; + QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end; + + QMutexLocker locker(&engine->mutex); + + //find all InternetAccessPoints + for (it = engine->accessPointConfigurations.begin(), + end = engine->accessPointConfigurations.end(); it != end; ++it) { + QNetworkConfigurationPrivatePointer ptr = it.value(); + + QMutexLocker configLocker(&ptr->mutex); + + if ((ptr->state & filter) == filter) { + QNetworkConfiguration pt; + pt.d = ptr; + result << pt; + } + } + + //find all service networks + for (it = engine->snapConfigurations.begin(), + end = engine->snapConfigurations.end(); it != end; ++it) { + QNetworkConfigurationPrivatePointer ptr = it.value(); + + QMutexLocker configLocker(&ptr->mutex); + + if ((ptr->state & filter) == filter) { + QNetworkConfiguration pt; + pt.d = ptr; + result << pt; + } + } + } + + return result; +} + +QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier) +{ + QNetworkConfiguration item; + + QMutexLocker locker(&mutex); + + foreach (QBearerEngine *engine, sessionEngines) { + QMutexLocker locker(&engine->mutex); + + if (engine->accessPointConfigurations.contains(identifier)) + item.d = engine->accessPointConfigurations.value(identifier); + else if (engine->snapConfigurations.contains(identifier)) + item.d = engine->snapConfigurations.value(identifier); + else if (engine->userChoiceConfigurations.contains(identifier)) + item.d = engine->userChoiceConfigurations.value(identifier); + else + continue; + + return item; + } + + return item; +} + +bool QNetworkConfigurationManagerPrivate::isOnline() +{ + QMutexLocker locker(&mutex); + + return !onlineConfigurations.isEmpty(); +} + void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr) { QMutexLocker locker(&mutex); @@ -81,10 +275,14 @@ void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurati emit configurationAdded(item); } + ptr->mutex.lock(); if (ptr->state == QNetworkConfiguration::Active) { + ptr->mutex.unlock(); onlineConfigurations.insert(ptr->id); if (!firstUpdate && onlineConfigurations.count() == 1) emit onlineStateChanged(true); + } else { + ptr->mutex.unlock(); } } @@ -92,7 +290,9 @@ void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigura { QMutexLocker locker(&mutex); + ptr->mutex.lock(); ptr->isValid = false; + ptr->mutex.unlock(); if (!firstUpdate) { QNetworkConfiguration item; @@ -117,10 +317,12 @@ void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigura bool previous = !onlineConfigurations.isEmpty(); + ptr->mutex.lock(); if (ptr->state == QNetworkConfiguration::Active) onlineConfigurations.insert(ptr->id); else onlineConfigurations.remove(ptr->id); + ptr->mutex.unlock(); bool online = !onlineConfigurations.isEmpty(); @@ -154,6 +356,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() else sessionEngines.append(engine); + engine->moveToThread(QCoreApplicationPrivate::mainThread()); + connect(engine, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations())); connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)), @@ -165,7 +369,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() capFlags |= engine->capabilities(); - engine->requestUpdate(); + QMetaObject::invokeMethod(engine, "requestUpdate"); } } @@ -211,7 +415,7 @@ void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() for (int i = 0; i < sessionEngines.count(); ++i) { updatingEngines.insert(i); - sessionEngines.at(i)->requestUpdate(); + QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate"); } } @@ -266,7 +470,7 @@ void QNetworkConfigurationManagerPrivate::pollEngines() if ((forcedPolling && sessionEngines.at(i)->requiresPolling()) || sessionEngines.at(i)->configurationsInUse()) { pollingEngines.insert(i); - sessionEngines.at(i)->requestUpdate(); + QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate"); } } } @@ -278,7 +482,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling() ++forcedPolling; if (forcedPolling == 1) - startPolling(); + QMetaObject::invokeMethod(this, "startPolling"); } void QNetworkConfigurationManagerPrivate::disablePolling() |