summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-09-15 07:45:43 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-09-15 07:45:43 (GMT)
commitc1026caddce5261b7cb944e36fff30a006e6d8c1 (patch)
treeba686e54f286a65d735cc7d5844906848a537ea8 /src
parent1c1a5fe0e2d9e28be5e0e14732d79d34c9bb2a74 (diff)
parentada33b11092f278ae4f1280a6da07ffd151a31b6 (diff)
downloadQt-c1026caddce5261b7cb944e36fff30a006e6d8c1.zip
Qt-c1026caddce5261b7cb944e36fff30a006e6d8c1.tar.gz
Qt-c1026caddce5261b7cb944e36fff30a006e6d8c1.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public: Refactor dangerous multiple inheritance Fix RConnection handle leak in symbian bearer plugin Prevent crash when cache is changed on the fly
Diffstat (limited to 'src')
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp23
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h2
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp173
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h30
4 files changed, 145 insertions, 83 deletions
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index a7a6287..209d064 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -451,6 +451,7 @@ bool QNetworkReplyImplPrivate::isCachingEnabled() const
void QNetworkReplyImplPrivate::setCachingEnabled(bool enable)
{
+ Q_Q(QNetworkReplyImpl);
if (!enable && !cacheEnabled)
return; // nothing to do
if (enable && cacheEnabled)
@@ -473,15 +474,27 @@ void QNetworkReplyImplPrivate::setCachingEnabled(bool enable)
networkCache()->remove(url);
cacheSaveDevice = 0;
cacheEnabled = false;
+ QObject::disconnect(networkCache(), SIGNAL(destroyed()), q, SLOT(_q_cacheDestroyed()));
}
}
+void QNetworkReplyImplPrivate::_q_cacheDestroyed()
+{
+ //destruction of cache invalidates cacheSaveDevice
+ cacheSaveDevice = 0;
+ cacheEnabled = false;
+}
+
void QNetworkReplyImplPrivate::completeCacheSave()
{
- if (cacheEnabled && errorCode != QNetworkReplyImpl::NoError) {
- networkCache()->remove(url);
- } else if (cacheEnabled && cacheSaveDevice) {
- networkCache()->insert(cacheSaveDevice);
+ Q_Q(QNetworkReplyImpl);
+ if (cacheEnabled) {
+ if (errorCode != QNetworkReplyImpl::NoError) {
+ networkCache()->remove(url);
+ } else if (cacheSaveDevice) {
+ networkCache()->insert(cacheSaveDevice);
+ }
+ QObject::disconnect(networkCache(), SIGNAL(destroyed()), q, SLOT(_q_cacheDestroyed()));
}
cacheSaveDevice = 0;
cacheEnabled = false;
@@ -541,6 +554,8 @@ void QNetworkReplyImplPrivate::initCacheSaveDevice()
networkCache()->remove(url);
cacheSaveDevice = 0;
cacheEnabled = false;
+ } else {
+ q->connect(networkCache(), SIGNAL(destroyed()), SLOT(_q_cacheDestroyed()));
}
}
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 31da297..0e4ff8f 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -103,6 +103,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_cacheDestroyed())
};
class QNetworkReplyImplPrivate: public QNetworkReplyPrivate
@@ -139,6 +140,7 @@ public:
void _q_networkSessionConnected();
void _q_networkSessionFailed();
#endif
+ void _q_cacheDestroyed();
void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
QIODevice *outgoingData);
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 5639c4f..5514511 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -61,13 +61,12 @@
QT_BEGIN_NAMESPACE
QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
-: CActive(CActive::EPriorityUserInput), engine(engine),
- iDynamicUnSetdefaultif(0), ipConnectionNotifier(0),
+: engine(engine),
+ ipConnectionNotifier(0), ipConnectionStarter(0),
iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false),
iClosedByUser(false), iError(QNetworkSession::UnknownSessionError), iALREnabled(0),
iConnectInBackground(false), isOpening(false)
{
- CActiveScheduler::Add(this);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
iMobility = NULL;
@@ -89,33 +88,44 @@ QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
TRAP_IGNORE(iConnectionMonitor.ConnectL());
}
-QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
+void QNetworkSessionPrivateImpl::closeHandles()
{
- isOpen = false;
- isOpening = false;
-
// Cancel Connection Progress Notifications first.
- // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start()
+ // Note: ConnectionNotifier must be destroyed before RConnection::Close()
// => deleting ipConnectionNotifier results RConnection::CancelProgressNotification()
delete ipConnectionNotifier;
ipConnectionNotifier = NULL;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- if (iMobility) {
- delete iMobility;
- iMobility = NULL;
- }
+ // mobility monitor must be deleted before RConnection is closed
+ delete iMobility;
+ iMobility = NULL;
#endif
- // Cancel possible RConnection::Start()
- Cancel();
- iSocketServ.Close();
+ // Cancel possible RConnection::Start() - may call RConnection::Close if Start was in progress
+ delete ipConnectionStarter;
+ ipConnectionStarter = 0;
+ //close any open connection (note Close twice is safe in case Cancel did it above)
+ iConnection.Close();
// Close global 'Open C' RConnection
// Clears also possible unsetdefaultif() flags.
setdefaultif(0);
iConnectionMonitor.Close();
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this)
+ << " - handles closed";
+#endif
+ iSocketServ.Close();
+}
+
+QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
+{
+ isOpen = false;
+ isOpening = false;
+
+ closeHandles();
iOpenCLibrary.Close();
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this)
@@ -166,7 +176,7 @@ void QNetworkSessionPrivateImpl::configurationAdded(QNetworkConfigurationPrivate
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
<< "configurationAdded IAP: "
- << toSymbianConfig(privateConfiguration(config))->numericIdentifier();
+ << toSymbianConfig(config)->numericIdentifier();
#endif
syncStateWithInterface();
@@ -372,7 +382,8 @@ void QNetworkSessionPrivateImpl::open()
syncStateWithInterface();
return;
}
-
+
+ Q_ASSERT(!iConnection.SubSessionHandle());
error = iConnection.Open(iSocketServ);
if (error != KErrNone) {
// Could not open RConnection
@@ -414,9 +425,9 @@ void QNetworkSessionPrivateImpl::open()
pref.SetIapId(symbianConfig->numericIdentifier());
#endif
- iConnection.Start(pref, iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start(pref);
}
// Avoid flip flop of states if the configuration is already
// active. IsOpen/opened() will indicate when ready.
@@ -442,9 +453,9 @@ void QNetworkSessionPrivateImpl::open()
#else
TConnSnapPref snapPref(symbianConfig->numericIdentifier());
#endif
- iConnection.Start(snapPref, iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start(snapPref);
}
// Avoid flip flop of states if the configuration is already
// active. IsOpen/opened() will indicate when ready.
@@ -453,9 +464,9 @@ void QNetworkSessionPrivateImpl::open()
}
} else if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
iKnownConfigsBeforeConnectionStart = engine->accessPointConfigurationIdentifiers();
- iConnection.Start(iStatus);
- if (!IsActive()) {
- SetActive();
+ if (!ipConnectionStarter) {
+ ipConnectionStarter = new ConnectionStarter(*this, iConnection);
+ ipConnectionStarter->Start();
}
newState(QNetworkSession::Connecting);
}
@@ -465,9 +476,7 @@ void QNetworkSessionPrivateImpl::open()
isOpening = false;
iError = QNetworkSession::UnknownSessionError;
emit QNetworkSessionPrivate::error(iError);
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
syncStateWithInterface();
}
}
@@ -521,21 +530,10 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
serviceConfig = QNetworkConfiguration();
-#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- if (iMobility) {
- delete iMobility;
- iMobility = NULL;
- }
-#endif
+ closeHandles();
- if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
- ipConnectionNotifier->StopNotifications();
- // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
- iHandleStateNotificationsFromManager = true;
- }
-
- Cancel(); // closes iConnection
- iSocketServ.Close();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
// Close global 'Open C' RConnection. If OpenC supports,
// close the defaultif for good to avoid difficult timing
@@ -759,12 +757,14 @@ void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*
}
}
-void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
+void QNetworkSessionPrivateImpl::Error(TInt aError)
{
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
- << "roaming Error() occurred, isOpen is: " << isOpen;
+ << "roaming Error() occurred" << aError << ", isOpen is: " << isOpen;
#endif
+ if (aError == KErrCancel)
+ return; //avoid recursive deletion
if (isOpen) {
isOpen = false;
isOpening = false;
@@ -772,10 +772,7 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::RoamingError;
emit QNetworkSessionPrivate::error(iError);
- Cancel();
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
QT_TRY {
syncStateWithInterface();
// In some cases IAP is still in Connected state when
@@ -1069,13 +1066,14 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
return publicConfig;
}
-void QNetworkSessionPrivateImpl::RunL()
+void QNetworkSessionPrivateImpl::ConnectionStartComplete(TInt statusCode)
{
#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
- << "RConnection::RunL with status code: " << iStatus.Int();
+ << "RConnection::Start completed with status code: " << statusCode;
#endif
- TInt statusCode = iStatus.Int();
+ delete ipConnectionStarter;
+ ipConnectionStarter = 0;
switch (statusCode) {
case KErrNone: // Connection created successfully
@@ -1102,18 +1100,13 @@ void QNetworkSessionPrivateImpl::RunL()
isOpening = false;
iError = QNetworkSession::UnknownSessionError;
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
+ closeHandles();
if (!newActiveConfig.isValid()) {
// No valid configuration, bail out.
// Status updates from QNCM won't be received correctly
// because there is no configuration to associate them with so transit here.
- iConnection.Close();
newState(QNetworkSession::Closing);
newState(QNetworkSession::Disconnected);
- } else {
- Cancel();
}
QT_TRYCATCH_LEAVING(syncStateWithInterface());
return;
@@ -1156,10 +1149,7 @@ void QNetworkSessionPrivateImpl::RunL()
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::InvalidConfigurationError;
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
case KErrCancel: // Connection attempt cancelled
@@ -1178,20 +1168,12 @@ void QNetworkSessionPrivateImpl::RunL()
iError = QNetworkSession::UnknownSessionError;
}
QT_TRYCATCH_LEAVING(emit QNetworkSessionPrivate::error(iError));
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
QT_TRYCATCH_LEAVING(syncStateWithInterface());
break;
}
}
-void QNetworkSessionPrivateImpl::DoCancel()
-{
- iConnection.Close();
-}
-
// Enters newState if feasible according to current state.
// AccessPointId may be given as parameter. If it is zero, state-change is assumed to
// concern this session's configuration. If non-zero, the configuration is looked up
@@ -1273,10 +1255,7 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
serviceConfig = QNetworkConfiguration();
iError = QNetworkSession::SessionAbortedError;
emit QNetworkSessionPrivate::error(iError);
- if (ipConnectionNotifier) {
- ipConnectionNotifier->StopNotifications();
- }
- Cancel();
+ closeHandles();
// Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
iHandleStateNotificationsFromManager = true;
emitSessionClosed = true; // Emit SessionClosed after state change has been reported
@@ -1583,6 +1562,50 @@ void ConnectionProgressNotifier::RunL()
}
}
+ConnectionStarter::ConnectionStarter(QNetworkSessionPrivateImpl &owner, RConnection &connection)
+ : CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
+{
+ CActiveScheduler::Add(this);
+}
+
+ConnectionStarter::~ConnectionStarter()
+{
+ Cancel();
+}
+
+void ConnectionStarter::Start()
+{
+ if (!IsActive()) {
+ iConnection.Start(iStatus);
+ SetActive();
+ }
+}
+
+void ConnectionStarter::Start(TConnPref &pref)
+{
+ if (!IsActive()) {
+ iConnection.Start(pref, iStatus);
+ SetActive();
+ }
+}
+
+void ConnectionStarter::RunL()
+{
+ iOwner.ConnectionStartComplete(iStatus.Int());
+ //note owner deletes on callback
+}
+
+TInt ConnectionStarter::RunError(TInt err)
+{
+ qWarning() << "ConnectionStarter::RunError" << err;
+ return KErrNone;
+}
+
+void ConnectionStarter::DoCancel()
+{
+ iConnection.Close();
+}
+
QT_END_NAMESPACE
#endif //QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
index 774b988..a5a4f87 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.h
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -68,11 +68,12 @@
QT_BEGIN_NAMESPACE
class ConnectionProgressNotifier;
+class ConnectionStarter;
class SymbianEngine;
typedef void (*TOpenCUnSetdefaultifFunction)();
-class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive
+class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
, public MMobilityProtocolResp
#endif
@@ -125,7 +126,7 @@ public: // From MMobilityProtocolResp
#endif
protected: // From CActive
- void RunL();
+ void ConnectionStartComplete(TInt statusCode);
void DoCancel();
private Q_SLOTS:
@@ -149,6 +150,7 @@ private:
bool easyWlanTrueIapId(TUint32 &trueIapId) const;
#endif
+ void closeHandles();
private: // data
SymbianEngine *engine;
@@ -166,12 +168,13 @@ private: // data
mutable RConnection iConnection;
mutable RConnectionMonitor iConnectionMonitor;
ConnectionProgressNotifier* ipConnectionNotifier;
-
+ ConnectionStarter* ipConnectionStarter;
+
bool iHandleStateNotificationsFromManager;
bool iFirstSync;
bool iStoppedByUser;
bool iClosedByUser;
-
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
CActiveCommsMobilityApiExt* iMobility;
#endif
@@ -189,6 +192,7 @@ private: // data
bool isOpening;
friend class ConnectionProgressNotifier;
+ friend class ConnectionStarter;
};
class ConnectionProgressNotifier : public CActive
@@ -211,6 +215,24 @@ private: // Data
};
+class ConnectionStarter : public CActive
+{
+public:
+ ConnectionStarter(QNetworkSessionPrivateImpl &owner, RConnection &connection);
+ ~ConnectionStarter();
+
+ void Start();
+ void Start(TConnPref &pref);
+protected:
+ void RunL();
+ TInt RunError(TInt err);
+ void DoCancel();
+
+private: // Data
+ QNetworkSessionPrivateImpl &iOwner;
+ RConnection& iConnection;
+};
+
QT_END_NAMESPACE
#endif //QNETWORKSESSION_IMPL_H