From cf69144f2b5511c6e4e81bd9da8ee6acd2340e5c Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Mon, 8 Mar 2010 13:04:13 +1000 Subject: Make QNetworkConfigurationManager and QNetworkConfiguration threadsafe. --- src/network/bearer/qbearerengine_p.h | 4 +- src/network/bearer/qnetworkconfigmanager.cpp | 169 +--------------- src/network/bearer/qnetworkconfigmanager_p.cpp | 218 +++++++++++++++++++- src/network/bearer/qnetworkconfigmanager_p.h | 7 +- src/network/bearer/qnetworkconfiguration.cpp | 60 +++++- src/network/bearer/qnetworkconfiguration_p.h | 22 +- src/plugins/bearer/corewlan/qcorewlanengine.h | 2 +- src/plugins/bearer/corewlan/qcorewlanengine.mm | 36 +++- src/plugins/bearer/generic/qgenericengine.cpp | 20 +- src/plugins/bearer/generic/qgenericengine.h | 2 +- src/plugins/bearer/icd/qicdengine.cpp | 25 ++- src/plugins/bearer/icd/qicdengine.h | 2 +- src/plugins/bearer/icd/qnetworksession_impl.cpp | 221 ++++++++++++++------- .../bearer/nativewifi/qnativewifiengine.cpp | 23 ++- src/plugins/bearer/nativewifi/qnativewifiengine.h | 2 +- .../networkmanager/qnetworkmanagerengine.cpp | 60 +++++- .../bearer/networkmanager/qnetworkmanagerengine.h | 2 +- src/plugins/bearer/nla/qnlaengine.cpp | 14 +- src/plugins/bearer/nla/qnlaengine.h | 2 +- .../bearer/symbian/qnetworksession_impl.cpp | 198 ++++++++++++++---- src/plugins/bearer/symbian/symbianengine.cpp | 56 +++++- src/plugins/bearer/symbian/symbianengine.h | 2 +- 22 files changed, 818 insertions(+), 329 deletions(-) diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h index 028c174..fd4bf87 100644 --- a/src/network/bearer/qbearerengine_p.h +++ b/src/network/bearer/qbearerengine_p.h @@ -73,7 +73,7 @@ class Q_NETWORK_EXPORT QBearerEngine : public QObject { Q_OBJECT - friend class QNetworkConfigurationManager; + friend class QNetworkConfigurationManagerPrivate; public: QBearerEngine(QObject *parent = 0); @@ -81,8 +81,6 @@ public: virtual bool hasIdentifier(const QString &id) = 0; - virtual void requestUpdate() = 0; - virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0; virtual QNetworkSessionPrivate *createSessionBackend() = 0; diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index b631cf1..e7595a4 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -212,114 +212,7 @@ QNetworkConfigurationManager::~QNetworkConfigurationManager() */ QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const { - QNetworkConfigurationManagerPrivate *conPriv = connManager(); - - foreach (QBearerEngine *engine, conPriv->engines()) { - 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, conPriv->engines()) { - QHash::Iterator it; - QHash::Iterator end; - - QMutexLocker locker(&engine->mutex); - - for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end(); - it != end; ++it) { - if ((it.value()->state & QNetworkConfiguration::Active) == - QNetworkConfiguration::Active) { - QNetworkConfiguration config; - config.d = it.value(); - return config; - } else if (!defaultConfiguration) { - if ((it.value()->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { - defaultConfiguration = it.value(); - } - } - } - } - - // 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, conPriv->engines()) { - QHash::Iterator it; - QHash::Iterator end; - - QMutexLocker locker(&engine->mutex); - - for (it = engine->accessPointConfigurations.begin(), - end = engine->accessPointConfigurations.end(); it != end; ++it) { - - if ((it.value()->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { - if (!defaultConfiguration) { - defaultConfiguration = it.value(); - } else { - if (defaultConfiguration->state == it.value()->state) { - if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) { - // do nothing - } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) { - // ethernet beats wlan - if (it.value()->bearerName() == QLatin1String("Ethernet")) - defaultConfiguration = it.value(); - } else { - // ethernet and wlan beats other - if (it.value()->bearerName() == QLatin1String("Ethernet") || - it.value()->bearerName() == QLatin1String("WLAN")) { - defaultConfiguration = it.value(); - } - } - } else { - // active beats discovered - if ((defaultConfiguration->state & QNetworkConfiguration::Active) != - QNetworkConfiguration::Active) { - defaultConfiguration = it.value(); - } - } - } - } - } - } - - // No Active InternetAccessPoint return first Discovered InternetAccessPoint. - if (defaultConfiguration) { - QNetworkConfiguration config; - config.d = defaultConfiguration; - return config; - } - - return QNetworkConfiguration(); + return connManager()->defaultConfiguration(); } /*! @@ -349,37 +242,7 @@ QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const */ QList QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const { - QList result; - QNetworkConfigurationManagerPrivate* conPriv = connManager(); - - foreach (QBearerEngine *engine, conPriv->engines()) { - QHash::Iterator it; - QHash::Iterator end; - - QMutexLocker locker(&engine->mutex); - - //find all InternetAccessPoints - for (it = engine->accessPointConfigurations.begin(), - end = engine->accessPointConfigurations.end(); it != end; ++it) { - if ((it.value()->state & filter) == filter) { - QNetworkConfiguration pt; - pt.d = it.value(); - result << pt; - } - } - - //find all service networks - for (it = engine->snapConfigurations.begin(), - end = engine->snapConfigurations.end(); it != end; ++it) { - if ((it.value()->state & filter) == filter) { - QNetworkConfiguration pt; - pt.d = it.value(); - result << pt; - } - } - } - - return result; + return connManager()->allConfigurations(filter); } /*! @@ -388,28 +251,9 @@ QList QNetworkConfigurationManager::allConfigurations(QNe \sa QNetworkConfiguration::identifier() */ -QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString& identifier) const +QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString &identifier) const { - QNetworkConfigurationManagerPrivate* conPriv = connManager(); - - QNetworkConfiguration item; - - foreach (QBearerEngine *engine, conPriv->engines()) { - 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; + return connManager()->configurationFromIdentifier(identifier); } /*! @@ -424,10 +268,7 @@ QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier( */ bool QNetworkConfigurationManager::isOnline() const { - QNetworkConfigurationManagerPrivate* conPriv = connManager(); - Q_UNUSED(conPriv); - QList activeConfigs = allConfigurations(QNetworkConfiguration::Active); - return activeConfigs.count() > 0; + return connManager()->isOnline(); } /*! 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 #include #include +#include #include 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"); 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::Iterator it; + QHash::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::Iterator it; + QHash::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 QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) +{ + QList result; + + QMutexLocker locker(&mutex); + + foreach (QBearerEngine *engine, sessionEngines) { + QHash::Iterator it; + QHash::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() diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index ac8518c..8ec8152 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -66,11 +66,16 @@ class QTimer; class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject { Q_OBJECT + public: QNetworkConfigurationManagerPrivate(); virtual ~QNetworkConfigurationManagerPrivate(); QNetworkConfiguration defaultConfiguration(); + QList allConfigurations(QNetworkConfiguration::StateFlags filter); + QNetworkConfiguration configurationFromIdentifier(const QString &identifier); + + bool isOnline(); QNetworkConfigurationManager::Capabilities capFlags; @@ -78,7 +83,7 @@ public: QList engines(); - void startPolling(); + Q_INVOKABLE void startPolling(); void enablePolling(); void disablePolling(); diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index c4ba406..82669e0 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -246,7 +246,11 @@ bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const */ QString QNetworkConfiguration::name() const { - return d ? d->name : QString(); + if (!d) + return QString(); + + QMutexLocker locker(&d->mutex); + return d->name; } /*! @@ -255,7 +259,11 @@ QString QNetworkConfiguration::name() const */ QString QNetworkConfiguration::identifier() const { - return d ? d->id : QString(); + if (!d) + return QString(); + + QMutexLocker locker(&d->mutex); + return d->id; } /*! @@ -268,7 +276,11 @@ QString QNetworkConfiguration::identifier() const */ QNetworkConfiguration::Type QNetworkConfiguration::type() const { - return d ? d->type : QNetworkConfiguration::Invalid; + if (!d) + return QNetworkConfiguration::Invalid; + + QMutexLocker locker(&d->mutex); + return d->type; } /*! @@ -283,7 +295,11 @@ QNetworkConfiguration::Type QNetworkConfiguration::type() const */ bool QNetworkConfiguration::isValid() const { - return d ? d->isValid : false; + if (!d) + return false; + + QMutexLocker locker(&d->mutex); + return d->isValid; } /*! @@ -291,7 +307,11 @@ bool QNetworkConfiguration::isValid() const */ QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const { - return d ? d->state : QNetworkConfiguration::Undefined; + if (!d) + return QNetworkConfiguration::Undefined; + + QMutexLocker locker(&d->mutex); + return d->state; } /*! @@ -303,7 +323,11 @@ QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const */ QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const { - return d ? d->purpose : QNetworkConfiguration::UnknownPurpose; + if (!d) + return QNetworkConfiguration::UnknownPurpose; + + QMutexLocker locker(&d->mutex); + return d->purpose; } /*! @@ -311,7 +335,11 @@ QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const */ bool QNetworkConfiguration::isRoamingAvailable() const { - return d ? d->roamingSupported : false; + if (!d) + return false; + + QMutexLocker locker(&d->mutex); + return d->roamingSupported; } /*! @@ -322,15 +350,25 @@ bool QNetworkConfiguration::isRoamingAvailable() const QList QNetworkConfiguration::children() const { QList results; - if (type() != QNetworkConfiguration::ServiceNetwork || !isValid() ) + + if (type() != QNetworkConfiguration::ServiceNetwork || !isValid()) return results; + QMutexLocker locker(&d->mutex); + QMutableListIterator iter(d->serviceNetworkMembers); - while(iter.hasNext()) { + while (iter.hasNext()) { QNetworkConfigurationPrivatePointer p = iter.next(); + //if we have an invalid member get rid of it -> was deleted earlier on - if (!p->isValid) - iter.remove(); + { + QMutexLocker childLocker(&p->mutex); + + if (!p->isValid) { + iter.remove(); + continue; + } + } QNetworkConfiguration item; item.d = p; diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 6b40946..6908277 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -54,7 +54,9 @@ // #include "qnetworkconfiguration.h" + #include +#include #include QT_BEGIN_NAMESPACE @@ -64,8 +66,9 @@ class QNetworkConfigurationPrivate : public QSharedData { public: QNetworkConfigurationPrivate () - : isValid(false), type(QNetworkConfiguration::Invalid), - roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), internet(false) + : mutex(QMutex::Recursive), type(QNetworkConfiguration::Invalid), + purpose(QNetworkConfiguration::UnknownPurpose), + isValid(false), roamingSupported(false) { } @@ -77,26 +80,27 @@ public: virtual QString bearerName() const { + QMutexLocker locker(&mutex); + return bearer; } - QString bearer; + mutable QMutex mutex; + QString bearer; QString name; - - bool isValid; QString id; + QNetworkConfiguration::StateFlags state; QNetworkConfiguration::Type type; - bool roamingSupported; QNetworkConfiguration::Purpose purpose; - bool internet; - QList serviceNetworkMembers; -private: + bool isValid; + bool roamingSupported; +private: // disallow detaching QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other); QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h index cbaa9d6..4fb9fdb 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.h +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -68,7 +68,7 @@ public: void connectToId(const QString &id); void disconnectFromId(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkSession::State sessionStateForId(const QString &id); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index cb278d9..26ea84f 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -240,7 +240,9 @@ void QCoreWlanEngine::connectToId(const QString &id) bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; if(!result) { + locker.unlock(); emit connectionError(id, ConnectError); + locker.relock(); } else { [autoreleasepool release]; return; @@ -252,11 +254,15 @@ void QCoreWlanEngine::connectToId(const QString &id) index++; } + locker.unlock(); emit connectionError(id, InterfaceLookupError); + locker.relock(); #endif } else { // not wifi } + + locker.unlock(); emit connectionError(id, OperationNotSupported); [autoreleasepool release]; } @@ -272,7 +278,9 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; [wifiInterface disassociate]; if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { + locker.unlock(); emit connectionError(id, DisconnectionError); + locker.relock(); } [autoreleasepool release]; return; @@ -280,13 +288,13 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) } else { } + + locker.unlock(); emit connectionError(id, OperationNotSupported); } void QCoreWlanEngine::requestUpdate() { - QMutexLocker locker(&mutex); - doRequestUpdate(); } @@ -340,6 +348,8 @@ void QCoreWlanEngine::doRequestUpdate() bool changed = false; + ptr->mutex.lock(); + if (!ptr->isValid) { ptr->isValid = true; changed = true; @@ -360,8 +370,13 @@ void QCoreWlanEngine::doRequestUpdate() changed = true; } - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } } } @@ -369,9 +384,13 @@ void QCoreWlanEngine::doRequestUpdate() QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); configurationInterface.remove(ptr->id); + + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } + locker.unlock(); emit updateCompleted(); } @@ -418,6 +437,8 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) bool changed = false; + ptr->mutex.lock(); + if (!ptr->isValid) { ptr->isValid = true; changed = true; @@ -438,8 +459,13 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) changed = true; } - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } } else { QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); @@ -453,7 +479,9 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) accessPointConfigurations.insert(id, ptr); configurationInterface.insert(id, interfaceName); + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } } diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp index a9e78b2..dfc74f2 100644 --- a/src/plugins/bearer/generic/qgenericengine.cpp +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -50,6 +50,7 @@ #include #include +#include #ifdef Q_OS_WIN #include "../platformdefs_win.h" @@ -174,8 +175,6 @@ void QGenericEngine::disconnectFromId(const QString &id) void QGenericEngine::requestUpdate() { - QMutexLocker locker(&mutex); - doRequestUpdate(); } @@ -231,6 +230,8 @@ void QGenericEngine::doRequestUpdate() bool changed = false; + ptr->mutex.lock(); + if (!ptr->isValid) { ptr->isValid = true; changed = true; @@ -251,8 +252,13 @@ void QGenericEngine::doRequestUpdate() changed = true; } - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } } else { QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); @@ -266,7 +272,9 @@ void QGenericEngine::doRequestUpdate() accessPointConfigurations.insert(id, ptr); configurationInterface.insert(id, interface.name()); + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } @@ -275,9 +283,13 @@ void QGenericEngine::doRequestUpdate() accessPointConfigurations.take(previous.takeFirst()); configurationInterface.remove(ptr->id); + + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } + locker.unlock(); emit updateCompleted(); } @@ -290,6 +302,8 @@ QNetworkSession::State QGenericEngine::sessionStateForId(const QString &id) if (!ptr) return QNetworkSession::Invalid; + QMutexLocker configLocker(&ptr->mutex); + if (!ptr->isValid) { return QNetworkSession::Invalid; } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h index a1b9167..616a3fd 100644 --- a/src/plugins/bearer/generic/qgenericengine.h +++ b/src/plugins/bearer/generic/qgenericengine.h @@ -68,7 +68,7 @@ public: void connectToId(const QString &id); void disconnectFromId(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkSession::State sessionStateForId(const QString &id); diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp index 5e506ef..5e9dc0a 100644 --- a/src/plugins/bearer/icd/qicdengine.cpp +++ b/src/plugins/bearer/icd/qicdengine.cpp @@ -180,7 +180,10 @@ void QIcdEngine::doRequestUpdate() ptr->roamingSupported = false; userChoiceConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } /* We return currently configured IAPs in the first run and do the WLAN @@ -241,7 +244,10 @@ void QIcdEngine::doRequestUpdate() QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(iap_id, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); #ifdef BEARER_MANAGEMENT_DEBUG qDebug("IAP: %s, name: %s, ssid: %s, added to known list", @@ -299,6 +305,8 @@ void QIcdEngine::doRequestUpdate() bool changed = false; + ptr->mutex.lock(); + if (!ptr->isValid) { ptr->isValid = true; changed = true; @@ -319,8 +327,13 @@ void QIcdEngine::doRequestUpdate() iapid.toAscii().data(), scanned_ssid.data()); #endif - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } if (!ap.scan.network_type.startsWith("WLAN")) continue; // not a wlan AP @@ -354,7 +367,10 @@ void QIcdEngine::doRequestUpdate() QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } } @@ -363,11 +379,15 @@ void QIcdEngine::doRequestUpdate() QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } - if (sender()) + if (sender()) { + locker.unlock(); emit updateCompleted(); + } } void QIcdEngine::deleteConfiguration(const QString &iap_id) @@ -384,6 +404,7 @@ void QIcdEngine::deleteConfiguration(const QString &iap_id) qDebug() << "IAP" << iap_id << "was removed from storage."; #endif + locker.unlock(); emit configurationRemoved(ptr); } else { #ifdef BEARER_MANAGEMENT_DEBUG diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h index 6ebe40d..50cda62 100644 --- a/src/plugins/bearer/icd/qicdengine.h +++ b/src/plugins/bearer/icd/qicdengine.h @@ -86,7 +86,7 @@ public: bool hasIdentifier(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkConfigurationManager::Capabilities capabilities() const; diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp index bb81408..a2ae65c 100644 --- a/src/plugins/bearer/icd/qnetworksession_impl.cpp +++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp @@ -312,19 +312,42 @@ void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState) state = newState; if (state == QNetworkSession::Disconnected) { - isOpen = false; + isOpen = false; currentNetworkInterface.clear(); - if (publicConfig.type() == QNetworkConfiguration::UserChoice) - privateConfiguration(activeConfig)->state = QNetworkConfiguration::Defined; - privateConfiguration(publicConfig)->state = QNetworkConfiguration::Defined; + if (publicConfig.type() == QNetworkConfiguration::UserChoice) { + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(activeConfig)); + + icdConfig->mutex.lock(); + icdConfig->state = QNetworkConfiguration::Defined; + icdConfig->mutex.unlock(); + } + + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(publicConfig)); + + icdConfig->mutex.lock(); + icdConfig->state = QNetworkConfiguration::Defined; + icdConfig->mutex.unlock(); } else if (state == QNetworkSession::Connected) { - isOpen = true; + isOpen = true; if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - privateConfiguration(activeConfig)->state = QNetworkConfiguration::Active; - privateConfiguration(activeConfig)->type = QNetworkConfiguration::InternetAccessPoint; + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(activeConfig)); + + icdConfig->mutex.lock(); + icdConfig->state = QNetworkConfiguration::Active; + icdConfig->type = QNetworkConfiguration::InternetAccessPoint; + icdConfig->mutex.unlock(); } - privateConfiguration(publicConfig)->state = QNetworkConfiguration::Active; + + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(publicConfig)); + + icdConfig->mutex.lock(); + icdConfig->state = QNetworkConfiguration::Active; + icdConfig->mutex.unlock(); } emit stateChanged(newState); @@ -334,13 +357,22 @@ void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState) void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId) { if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - toIcdConfig(privateConfiguration(activeConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; - privateConfiguration(activeConfig)->id = newId; + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(activeConfig)); + + icdConfig->mutex.lock(); + icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME; + icdConfig->id = newId; + icdConfig->mutex.unlock(); } else { - toIcdConfig(privateConfiguration(publicConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME; - if (privateConfiguration(publicConfig)->id != newId) { - privateConfiguration(publicConfig)->id = newId; - } + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(publicConfig)); + + icdConfig->mutex.lock(); + icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME; + if (icdConfig->id != newId) + icdConfig->id = newId; + icdConfig->mutex.unlock(); } } @@ -368,10 +400,15 @@ quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const } } else { /* We probably will never get to this branch */ - if (res.params.network_id == toIcdConfig(privateConfiguration(activeConfig))->network_id) { - counter_tx = res.bytes_sent; - counter_rx = res.bytes_received; + IcdNetworkConfigurationPrivate *icdConfig = + toIcdConfig(privateConfiguration(activeConfig)); + + icdConfig->mutex.lock(); + if (res.params.network_id == icdConfig->network_id) { + counter_tx = res.bytes_sent; + counter_rx = res.bytes_received; } + icdConfig->mutex.unlock(); } } @@ -413,20 +450,25 @@ QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfigurat cpPriv = toIcdConfig(privateConfiguration(toConfig)); } - cpPriv->name = privateConfiguration(fromConfig)->name; - cpPriv->isValid = privateConfiguration(fromConfig)->isValid; + IcdNetworkConfigurationPrivate *fromPriv = toIcdConfig(privateConfiguration(fromConfig)); + + QMutexLocker toLocker(&cpPriv->mutex); + QMutexLocker fromLocker(&fromPriv->mutex); + + cpPriv->name = fromPriv->name; + cpPriv->isValid = fromPriv->isValid; // Note that we do not copy id field here as the publicConfig does // not contain a valid IAP id. - cpPriv->state = privateConfiguration(fromConfig)->state; - cpPriv->type = privateConfiguration(fromConfig)->type; - cpPriv->roamingSupported = privateConfiguration(fromConfig)->roamingSupported; - cpPriv->purpose = privateConfiguration(fromConfig)->purpose; - cpPriv->network_id = toIcdConfig(privateConfiguration(fromConfig))->network_id; - cpPriv->iap_type = toIcdConfig(privateConfiguration(fromConfig))->iap_type; - cpPriv->network_attrs = toIcdConfig(privateConfiguration(fromConfig))->network_attrs; - cpPriv->service_type = toIcdConfig(privateConfiguration(fromConfig))->service_type; - cpPriv->service_id = toIcdConfig(privateConfiguration(fromConfig))->service_id; - cpPriv->service_attrs = toIcdConfig(privateConfiguration(fromConfig))->service_attrs; + cpPriv->state = fromPriv->state; + cpPriv->type = fromPriv->type; + cpPriv->roamingSupported = fromPriv->roamingSupported; + cpPriv->purpose = fromPriv->purpose; + cpPriv->network_id = fromPriv->network_id; + cpPriv->iap_type = fromPriv->iap_type; + cpPriv->network_attrs = fromPriv->network_attrs; + cpPriv->service_type = fromPriv->service_type; + cpPriv->service_id = fromPriv->service_id; + cpPriv->service_attrs = fromPriv->service_attrs; return toConfig; } @@ -511,18 +553,30 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() * then do not update current state etc. */ if (publicConfig.type() == QNetworkConfiguration::UserChoice || - privateConfiguration(publicConfig)->id == state_results.first().params.network_id) { + publicConfig.identifier() == state_results.first().params.network_id) { switch (state_results.first().state) { case ICD_STATE_DISCONNECTED: state = QNetworkSession::Disconnected; - if (privateConfiguration(activeConfig)) - privateConfiguration(activeConfig)->isValid = true; + { + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + if (ptr) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); + } + } break; case ICD_STATE_CONNECTING: state = QNetworkSession::Connecting; - if (privateConfiguration(activeConfig)) - privateConfiguration(activeConfig)->isValid = true; + { + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + if (ptr) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); + } + } break; case ICD_STATE_CONNECTED: { @@ -540,6 +594,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + QMutexLocker configLocker(&ptr->mutex); + state = QNetworkSession::Connected; toIcdConfig(ptr)->network_id = state_results.first().params.network_id; ptr->id = toIcdConfig(ptr)->network_id; @@ -553,26 +609,35 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() ptr->isValid = true; currentNetworkInterface = get_network_interface(); - Maemo::IAPConf iap_name(privateConfiguration(activeConfig)->id); + Maemo::IAPConf iap_name(ptr->id); QString name_value = iap_name.value("name").toString(); if (!name_value.isEmpty()) - privateConfiguration(activeConfig)->name = name_value; + ptr->name = name_value; else - privateConfiguration(activeConfig)->name = privateConfiguration(activeConfig)->id; + ptr->name = ptr->id; // Add the new active configuration to manager or update the old config - if (!engine->hasIdentifier(privateConfiguration(activeConfig)->id)) - engine->addSessionConfiguration(privateConfiguration(activeConfig)); - else - engine->changedSessionConfiguration(privateConfiguration(activeConfig)); - } + if (!engine->hasIdentifier(ptr->id)) { + configLocker.unlock(); + engine->addSessionConfiguration(ptr); + } else { + configLocker.unlock(); + engine->changedSessionConfiguration(ptr); + } + } break; case ICD_STATE_DISCONNECTING: state = QNetworkSession::Closing; - if (privateConfiguration(activeConfig)) - privateConfiguration(activeConfig)->isValid = true; + { + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + if (ptr) { + ptr->mutex.lock(); + ptr->isValid = true; + ptr->mutex.unlock(); + } + } break; default: break; @@ -634,12 +699,16 @@ void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork() void QNetworkSessionPrivateImpl::clearConfiguration(QNetworkConfiguration &config) { - toIcdConfig(privateConfiguration(config))->network_id.clear(); - toIcdConfig(privateConfiguration(config))->iap_type.clear(); - toIcdConfig(privateConfiguration(config))->network_attrs = 0; - toIcdConfig(privateConfiguration(config))->service_type.clear(); - toIcdConfig(privateConfiguration(config))->service_id.clear(); - toIcdConfig(privateConfiguration(config))->service_attrs = 0; + IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); + + QMutexLocker locker(&icdConfig->mutex); + + icdConfig->network_id.clear(); + icdConfig->iap_type.clear(); + icdConfig->network_attrs = 0; + icdConfig->service_type.clear(); + icdConfig->service_id.clear(); + icdConfig->service_attrs = 0; } @@ -649,8 +718,8 @@ void QNetworkSessionPrivateImpl::updateStateFromActiveConfig() bool newActive = false; - if (!privateConfiguration(activeConfig)) - return; + if (!activeConfig.isValid()) + return; if (!activeConfig.isValid()) { state = QNetworkSession::Invalid; @@ -837,16 +906,21 @@ void QNetworkSessionPrivateImpl::do_open() QList params; Maemo::ConnectParams param; - param.connect.service_type = toIcdConfig(privateConfiguration(config))->service_type; - param.connect.service_attrs = toIcdConfig(privateConfiguration(config))->service_attrs; - param.connect.service_id = toIcdConfig(privateConfiguration(config))->service_id; - param.connect.network_type = toIcdConfig(privateConfiguration(config))->iap_type; - param.connect.network_attrs = toIcdConfig(privateConfiguration(config))->network_attrs; - if (toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME) + + IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); + + icdConfig->mutex.lock(); + param.connect.service_type = icdConfig->service_type; + param.connect.service_attrs = icdConfig->service_attrs; + param.connect.service_id = icdConfig->service_id; + param.connect.network_type = icdConfig->iap_type; + param.connect.network_attrs = icdConfig->network_attrs; + if (icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME) param.connect.network_id = QByteArray(iap.toLatin1()); else - param.connect.network_id = toIcdConfig(privateConfiguration(config))->network_id; + param.connect.network_id = icdConfig->network_id; params.append(param); + icdConfig->mutex.unlock(); #ifdef BEARER_MANAGEMENT_DEBUG qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s", @@ -887,26 +961,30 @@ void QNetworkSessionPrivateImpl::do_open() return; } + IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config)); /* Did we connect to non saved IAP? */ - if (!(toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)) { + icdConfig->mutex.lock(); + if (!(icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME)) { /* Because the connection succeeded, the IAP is now known. */ - toIcdConfig(privateConfiguration(config))->network_attrs |= ICD_NW_ATTR_IAPNAME; - privateConfiguration(config)->id = connected_iap; + icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME; + icdConfig->id = connected_iap; } /* User might have changed the IAP name when a new IAP was saved */ - Maemo::IAPConf iap_name(privateConfiguration(config)->id); + Maemo::IAPConf iap_name(icdConfig->id); QString name = iap_name.value("name").toString(); if (!name.isEmpty()) - privateConfiguration(config)->name = name; + icdConfig->name = name; + + icdConfig->iap_type = connect_result.connect.network_type; - toIcdConfig(privateConfiguration(config))->iap_type = connect_result.connect.network_type; + icdConfig->isValid = true; + icdConfig->state = QNetworkConfiguration::Active; + icdConfig->type = QNetworkConfiguration::InternetAccessPoint; - privateConfiguration(config)->isValid = true; - privateConfiguration(config)->state = QNetworkConfiguration::Active; - privateConfiguration(config)->type = QNetworkConfiguration::InternetAccessPoint; + icdConfig->mutex.unlock(); startTime = QDateTime::currentDateTime(); updateState(QNetworkSession::Connected); @@ -995,8 +1073,11 @@ void QNetworkSessionPrivateImpl::stop() * configurationChanged is emitted (below). */ - privateConfiguration(activeConfig)->state = QNetworkConfiguration::Discovered; - engine->changedSessionConfiguration(privateConfiguration(activeConfig)); + QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig); + ptr->mutex.lock(); + ptr->state = QNetworkConfiguration::Discovered; + ptr->mutex.unlock(); + engine->changedSessionConfiguration(ptr); opened = false; isOpen = false; diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp index b6522ad..6c74159 100644 --- a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp @@ -185,6 +185,8 @@ void QNativeWifiEngine::scanComplete() bool changed = false; + ptr->mutex.lock(); + if (!ptr->isValid) { ptr->isValid = true; changed = true; @@ -200,8 +202,13 @@ void QNativeWifiEngine::scanComplete() changed = true; } - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } } else { QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); @@ -214,7 +221,9 @@ void QNativeWifiEngine::scanComplete() accessPointConfigurations.insert(id, ptr); + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } @@ -227,9 +236,12 @@ void QNativeWifiEngine::scanComplete() QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } + locker.unlock(); emit updateCompleted(); } @@ -358,6 +370,7 @@ void QNativeWifiEngine::connectToId(const QString &id) #ifdef BEARER_MANAGEMENT_DEBUG qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); #endif + locker.unlock(); emit connectionError(id, InterfaceLookupError); return; } @@ -405,7 +418,9 @@ void QNativeWifiEngine::connectToId(const QString &id) #ifdef BEARER_MANAGEMENT_DEBUG qDebug("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result); #endif + locker.unlock(); emit connectionError(id, ConnectError); + locker.relock(); break; } @@ -415,8 +430,10 @@ void QNativeWifiEngine::connectToId(const QString &id) local_WlanFreeMemory(interfaceList); - if (profile.isEmpty()) + if (profile.isEmpty()) { + locker.unlock(); emit connectionError(id, InterfaceLookupError); + } } void QNativeWifiEngine::disconnectFromId(const QString &id) @@ -426,6 +443,7 @@ void QNativeWifiEngine::disconnectFromId(const QString &id) QString interface = getInterfaceFromId(id); if (interface.isEmpty()) { + locker.unlock(); emit connectionError(id, InterfaceLookupError); return; } @@ -446,6 +464,7 @@ void QNativeWifiEngine::disconnectFromId(const QString &id) #ifdef BEARER_MANAGEMENT_DEBUG qDebug("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result); #endif + locker.unlock(); emit connectionError(id, DisconnectionError); return; } diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.h b/src/plugins/bearer/nativewifi/qnativewifiengine.h index 56489b6..2005b2b 100644 --- a/src/plugins/bearer/nativewifi/qnativewifiengine.h +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.h @@ -78,7 +78,7 @@ public: void connectToId(const QString &id); void disconnectFromId(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkSession::State sessionStateForId(const QString &id); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 0fa8f3c..d7e315a 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -297,10 +297,17 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { + ptr->mutex.lock(); if (activeConnection->state() == 2 && ptr->state != QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Active; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } else { + ptr->mutex.unlock(); } } } @@ -313,9 +320,16 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path, QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(identifiers.takeFirst()); + ptr->mutex.lock(); if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Discovered; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } else { + ptr->mutex.unlock(); } } } @@ -339,10 +353,17 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { + ptr->mutex.lock(); if (activeConnection->state() == 2 && ptr->state != QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Active; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } else { + ptr->mutex.unlock(); } } } @@ -424,6 +445,8 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); } @@ -444,7 +467,8 @@ void QNetworkManagerEngine::removeConnection(const QString &path) connection->connectionInterface()->path())); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id); - ptr->isValid = false; + + locker.unlock(); emit configurationRemoved(ptr); } @@ -476,11 +500,16 @@ void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id); + ptr->mutex.lock(); + ptr->isValid = cpPriv->isValid; ptr->name = cpPriv->name; ptr->id = cpPriv->id; ptr->state = cpPriv->state; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); delete cpPriv; } @@ -500,10 +529,17 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { + ptr->mutex.lock(); if (activeConnection.state() == 2 && ptr->state != QNetworkConfiguration::Active) { ptr->state = QNetworkConfiguration::Active; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } else { + ptr->mutex.unlock(); } } } @@ -543,7 +579,11 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); + ptr->mutex.lock(); ptr->state = QNetworkConfiguration::Discovered; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); return; } @@ -562,6 +602,8 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec ptr->bearer = QLatin1String("WLAN"); accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); } @@ -592,7 +634,11 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); + ptr->mutex.lock(); ptr->state = QNetworkConfiguration::Defined; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); return; } @@ -601,8 +647,11 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path, QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(QString::number(qHash(objectPath.path()))); - if (ptr) + if (ptr) { + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); + } } delete accessPoint; @@ -633,7 +682,11 @@ void QNetworkManagerEngine::updateAccessPoint(const QMap &map QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(connectionId); + ptr->mutex.lock(); ptr->state = QNetworkConfiguration::Discovered; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); return; } @@ -687,7 +740,10 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri QString::number(qHash(accessPoints.at(i)->connectionInterface()->path())); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(accessPointId); + + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } break; } diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index ca1f857..05a1429 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -80,7 +80,7 @@ public: void connectToId(const QString &id); void disconnectFromId(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkSession::State sessionStateForId(const QString &id); diff --git a/src/plugins/bearer/nla/qnlaengine.cpp b/src/plugins/bearer/nla/qnlaengine.cpp index 334eb14..9ab9924 100644 --- a/src/plugins/bearer/nla/qnlaengine.cpp +++ b/src/plugins/bearer/nla/qnlaengine.cpp @@ -522,6 +522,8 @@ void QNlaEngine::networksChanged() bool changed = false; + ptr->mutex.lock(); + if (ptr->isValid != cpPriv->isValid) { ptr->isValid = cpPriv->isValid; changed = true; @@ -537,8 +539,13 @@ void QNlaEngine::networksChanged() changed = true; } - if (changed) + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + } delete cpPriv; } else { @@ -546,7 +553,9 @@ void QNlaEngine::networksChanged() accessPointConfigurations.insert(ptr->id, ptr); + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } @@ -554,9 +563,12 @@ void QNlaEngine::networksChanged() QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } + locker.unlock(); emit updateCompleted(); } diff --git a/src/plugins/bearer/nla/qnlaengine.h b/src/plugins/bearer/nla/qnlaengine.h index 14c5201..1d49464 100644 --- a/src/plugins/bearer/nla/qnlaengine.h +++ b/src/plugins/bearer/nla/qnlaengine.h @@ -90,7 +90,7 @@ public: void connectToId(const QString &id); void disconnectFromId(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkSession::State sessionStateForId(const QString &id); diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index bec562d..0737942 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -100,7 +100,7 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl() void QNetworkSessionPrivateImpl::syncStateWithInterface() { - if (!privateConfiguration(publicConfig)) + if (!publicConfig.isValid()) return; // Start monitoring changes in IAP states @@ -143,9 +143,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface() // There were no open connections to used IAP or SNAP if (iError == QNetworkSession::InvalidConfigurationError) { newState(QNetworkSession::Invalid); - } - else if ((privateConfiguration(publicConfig)->state & QNetworkConfiguration::Discovered) == - QNetworkConfiguration::Discovered) { + } else if ((publicConfig.state() & QNetworkConfiguration::Discovered) == + QNetworkConfiguration::Discovered) { newState(QNetworkSession::Disconnected); } else { newState(QNetworkSession::NotAvailable); @@ -293,10 +292,15 @@ void QNetworkSessionPrivateImpl::open() for (TUint i=1; i<=count; i++) { // Note: GetConnectionInfo expects 1-based index. if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) { - if (connInfo().iIapId == toSymbianConfig(privateConfiguration(publicConfig))->numericId) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (connInfo().iIapId == symbianConfig->numericId) { if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) { activeConfig = publicConfig; - activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); + activeInterface = interface(symbianConfig->numericId); connected = ETrue; startTime = QDateTime::currentDateTime(); if (iDynamicSetdefaultif) { @@ -320,7 +324,12 @@ void QNetworkSessionPrivateImpl::open() if (!connected) { TCommDbConnPref pref; pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); - pref.SetIapId(toSymbianConfig(privateConfiguration(publicConfig))->numericId); + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + symbianConfig->mutex.lock(); + pref.SetIapId(symbianConfig->numericId); + symbianConfig->mutex.unlock(); iConnection.Start(pref, iStatus); if (!IsActive()) { SetActive(); @@ -328,7 +337,12 @@ void QNetworkSessionPrivateImpl::open() newState(QNetworkSession::Connecting); } } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { - TConnSnapPref snapPref(toSymbianConfig(privateConfiguration(publicConfig))->numericId); + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + symbianConfig->mutex.lock(); + TConnSnapPref snapPref(symbianConfig->numericId); + symbianConfig->mutex.unlock(); iConnection.Start(snapPref, iStatus); if (!IsActive()) { SetActive(); @@ -387,7 +401,13 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals) return; } - TUint activeIap = toSymbianConfig(privateConfiguration(activeConfig))->numericId; + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(activeConfig)); + + symbianConfig->mutex.lock(); + TUint activeIap = symbianConfig->numericId; + symbianConfig->mutex.unlock(); + isOpen = false; activeConfig = QNetworkConfiguration(); serviceConfig = QNetworkConfiguration(); @@ -501,7 +521,13 @@ void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOld iALRUpgradingConnection = aIsUpgrade; QList configs = publicConfig.children(); for (int i=0; i < configs.count(); i++) { - if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == aNewAPInfo.AccessPoint()) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(configs[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->numericId == aNewAPInfo.AccessPoint()) { + configLocker.unlock(); emit preferredConfigurationChanged(configs[i], aIsSeamless); } } @@ -625,13 +651,24 @@ quint64 QNetworkSessionPrivateImpl::transferredData(TUint dataType) const if (config.type() == QNetworkConfiguration::ServiceNetwork) { QList configs = config.children(); for (int i=0; i < configs.count(); i++) { - if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == apId) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(configs[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->numericId == apId) { configFound = true; break; } } - } else if (toSymbianConfig(privateConfiguration(config))->numericId == apId) { - configFound = true; + } else { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(config)); + + symbianConfig->mutex.lock(); + if (symbianConfig->numericId == apId) + configFound = true; + symbianConfig->mutex.unlock(); } if (configFound) { TUint tData; @@ -668,9 +705,12 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia // Try to search IAP from the used SNAP using IAP Id QList children = publicConfig.children(); for (int i=0; i < children.count(); i++) { - if (toSymbianConfig(privateConfiguration(children[i]))->numericId == iapId) { + SymbianNetworkConfigurationPrivate *childConfig = + toSymbianConfig(privateConfiguration(children[i])); + + QMutexLocker childLocker(&childConfig->mutex); + if (childConfig->numericId == iapId) return children[i]; - } } // Given IAP Id was not found from the used SNAP @@ -682,10 +722,21 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia // <=> Note: It's possible that in this case reported IAP is // clone of the one of the IAPs of the used SNAP // => If mappingName matches, clone has been found - QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId))); - if (privateConfiguration(pt)) { + QNetworkConfiguration pt = QNetworkConfigurationManager() + .configurationFromIdentifier(QString::number(qHash(iapId))); + + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(pt)); + if (symbianConfig) { + QMutexLocker configLocker(&symbianConfig->mutex); + for (int i=0; i < children.count(); i++) { - if (toSymbianConfig(privateConfiguration(children[i]))->mappingName == toSymbianConfig(privateConfiguration(pt))->mappingName) { + SymbianNetworkConfigurationPrivate *childConfig = + toSymbianConfig(privateConfiguration(children[i])); + + QMutexLocker childLocker(&childConfig->mutex); + + if (childConfig->mappingName == symbianConfig->mappingName) { return children[i]; } } @@ -776,13 +827,21 @@ void QNetworkSessionPrivateImpl::RunL() iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this); } #endif + isOpen = true; activeConfig = newActiveConfig; - activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); + + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(activeConfig)); + + symbianConfig->mutex.lock(); + activeInterface = interface(symbianConfig->numericId); if (publicConfig.type() == QNetworkConfiguration::UserChoice) { - serviceConfig = QNetworkConfigurationManager().configurationFromIdentifier(toSymbianConfig(privateConfiguration(activeConfig))->serviceNetworkPtr->id); + serviceConfig = QNetworkConfigurationManager() + .configurationFromIdentifier(symbianConfig->serviceNetworkPtr->id); } - + symbianConfig->mutex.unlock(); + startTime = QDateTime::currentDateTime(); newState(QNetworkSession::Connected); @@ -830,7 +889,14 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork && newState == QNetworkSession::Connected) { activeConfig = activeConfiguration(accessPointId); - activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId); + + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(activeConfig)); + + symbianConfig->mutex.lock(); + activeInterface = interface(symbianConfig->numericId); + symbianConfig->mutex.unlock(); + #ifdef SNAP_FUNCTIONALITY_AVAILABLE if (iDynamicSetdefaultif) { // Use name of the IAP to set default IAP @@ -880,13 +946,25 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint retVal = true; } else { if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { - if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == accessPointId) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + QMutexLocker configLocker(&symbianConfig->mutex); + if (symbianConfig->numericId == accessPointId) { + configLocker.unlock(); + state = newState; emit stateChanged(state); retVal = true; } } else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) { - if (toSymbianConfig(privateConfiguration(activeConfig))->numericId == accessPointId) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(activeConfig)); + + QMutexLocker configLocker(&symbianConfig->mutex); + if (symbianConfig->numericId == accessPointId) { + configLocker.unlock(); + state = newState; emit stateChanged(state); retVal = true; @@ -894,11 +972,17 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { QList subConfigurations = publicConfig.children(); for (int i = 0; i < subConfigurations.count(); i++) { - if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == accessPointId) { + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(subConfigurations[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->numericId == accessPointId) { if (newState == QNetworkSession::Connected) { // Make sure that when AccessPoint is reported to be Connected // also state of the related configuration changes to Active. - privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Active; + symbianConfig->state = QNetworkConfiguration::Active; + configLocker.unlock(); state = newState; emit stateChanged(state); @@ -907,11 +991,14 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint if (newState == QNetworkSession::Disconnected) { // Make sure that when AccessPoint is reported to be disconnected // also state of the related configuration changes from Active to Defined. - privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Defined; + symbianConfig->state = QNetworkConfiguration::Defined; } QNetworkConfiguration config = bestConfigFromSNAP(publicConfig); if ((config.state() == QNetworkConfiguration::Defined) || (config.state() == QNetworkConfiguration::Discovered)) { + + configLocker.unlock(); + state = newState; emit stateChanged(state); retVal = true; @@ -1033,15 +1120,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent) if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { QList subConfigurations = publicConfig.children(); for (int i = 0; i < subConfigurations.count(); i++ ) { - if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) { - apId = toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId; + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(subConfigurations[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->connectionId == connectionId) { + apId = symbianConfig->numericId; break; } } } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { - if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) { - apId = toSymbianConfig(privateConfiguration(publicConfig))->numericId; - } + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + symbianConfig->mutex.lock(); + if (symbianConfig->connectionId == connectionId) + apId = symbianConfig->numericId; + symbianConfig->mutex.unlock(); } if (apId > 0) { @@ -1064,15 +1160,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent) if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { QList subConfigurations = publicConfig.children(); for (int i = 0; i < subConfigurations.count(); i++ ) { - if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == apId) { - toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = connectionId; + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(subConfigurations[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->numericId == apId) { + symbianConfig->connectionId = connectionId; break; } } } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { - if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == apId) { - toSymbianConfig(privateConfiguration(publicConfig))->connectionId = connectionId; - } + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + symbianConfig->mutex.lock(); + if (symbianConfig->numericId == apId) + symbianConfig->connectionId = connectionId; + symbianConfig->mutex.unlock(); } } } @@ -1087,15 +1192,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent) if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { QList subConfigurations = publicConfig.children(); for (int i = 0; i < subConfigurations.count(); i++ ) { - if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) { - toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = 0; + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(subConfigurations[i])); + + QMutexLocker configLocker(&symbianConfig->mutex); + + if (symbianConfig->connectionId == connectionId) { + symbianConfig->connectionId = 0; break; } } } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { - if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) { - toSymbianConfig(privateConfiguration(publicConfig))->connectionId = 0; - } + SymbianNetworkConfigurationPrivate *symbianConfig = + toSymbianConfig(privateConfiguration(publicConfig)); + + symbianConfig->mutex.lock(); + if (symbianConfig->connectionId == connectionId) + symbianConfig->connectionId = 0; + symbianConfig->mutex.unlock(); } } break; diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index 88a563c..980892a 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -75,6 +75,8 @@ SymbianNetworkConfigurationPrivate::~SymbianNetworkConfigurationPrivate() QString SymbianNetworkConfigurationPrivate::bearerName() const { + QMutexLocker locker(&mutex); + switch (bearer) { case BearerEthernet: return QLatin1String("Ethernet"); @@ -250,7 +252,10 @@ void SymbianEngine::updateConfigurationsL() if (error == KErrNone) { QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } } CleanupStack::PopAndDestroy(&connectionMethod); @@ -288,7 +293,10 @@ void SymbianEngine::updateConfigurationsL() QNetworkConfigurationPrivatePointer ptr(cpPriv); snapConfigurations.insert(ident, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); CleanupStack::Pop(cpPriv); } @@ -309,7 +317,11 @@ void SymbianEngine::updateConfigurationsL() QNetworkConfigurationPrivatePointer ptr(cpPriv); toSymbianConfig(ptr)->serviceNetworkPtr = privSNAP; accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); + privSNAP->serviceNetworkMembers.append(ptr); } } else { @@ -358,7 +370,9 @@ void SymbianEngine::updateConfigurationsL() QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ident, ptr); + locker.unlock(); emit configurationAdded(ptr); + locker.relock(); } else { delete cpPriv; } @@ -372,7 +386,10 @@ void SymbianEngine::updateConfigurationsL() foreach (const QString &oldIface, knownConfigs) { //remove non existing IAP QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface); + + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); // Remove non existing IAP from SNAPs foreach (const QString &iface, snapConfigurations.keys()) { @@ -391,7 +408,10 @@ void SymbianEngine::updateConfigurationsL() foreach (const QString &oldIface, knownSnapConfigs) { //remove non existing SNAPs QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface); + + locker.unlock(); emit configurationRemoved(ptr); + locker.relock(); } } @@ -596,7 +616,7 @@ QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL() } #endif - if (!ptr->isValid) { + if (!ptr || !ptr->isValid) { QString iface = QString::number(qHash(KUserChoiceIAPId)); ptr = userChoiceConfigurations.value(iface); } @@ -651,7 +671,9 @@ void SymbianEngine::updateActiveAccessPoints() if (iOnline != online) { iOnline = online; + locker.unlock(); emit this->onlineStateChanged(iOnline); + locker.relock(); } } @@ -704,7 +726,9 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn if (!iFirstUpdate) { startCommsDatabaseNotifications(); + locker.unlock(); emit updateCompleted(); + locker.relock(); } } @@ -746,10 +770,18 @@ bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePoint { QMutexLocker locker(&mutex); + ptr->mutex.lock(); if (newState != ptr->state) { ptr->state = newState; + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + return true; + } else { + ptr->mutex.unlock(); } return false; } @@ -763,10 +795,18 @@ bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivate { QMutexLocker locker(&mutex); + ptr->mutex.lock(); if ((newState | ptr->state) != ptr->state) { ptr->state = (ptr->state | newState); + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + return true; + } else { + ptr->mutex.unlock(); } return false; } @@ -781,10 +821,18 @@ bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivate { QMutexLocker locker(&mutex); + ptr->mutex.lock(); if ((newState & ptr->state) != ptr->state) { ptr->state = (newState & ptr->state); + ptr->mutex.unlock(); + + locker.unlock(); emit configurationChanged(ptr); + locker.relock(); + return true; + } else { + ptr->mutex.unlock(); } return false; } @@ -893,7 +941,10 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) if (!iOnline) { iOnline = true; + + locker.unlock(); emit this->onlineStateChanged(iOnline); + locker.relock(); } } } @@ -923,7 +974,10 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } if (iOnline != online) { iOnline = online; + + locker.unlock(); emit this->onlineStateChanged(iOnline); + locker.relock(); } } break; diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index ee6d070..e6af908 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -109,7 +109,7 @@ public: bool hasIdentifier(const QString &id); - void requestUpdate(); + Q_INVOKABLE void requestUpdate(); QNetworkConfigurationManager::Capabilities capabilities() const; -- cgit v0.12