summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMurray Read <ext-murray.2.read@nokia.com>2012-02-17 13:53:49 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-02-20 16:27:31 (GMT)
commit5641d4539e60a09e8b85e82605f902d78bbdeae9 (patch)
treed2bb6b0669ac4ca4e841577352a89a9f3953593c
parent2f7b750bd87402c6bb5ea5b8b9de9bb84060fe4d (diff)
downloadQt-5641d4539e60a09e8b85e82605f902d78bbdeae9.zip
Qt-5641d4539e60a09e8b85e82605f902d78bbdeae9.tar.gz
Qt-5641d4539e60a09e8b85e82605f902d78bbdeae9.tar.bz2
RR scheduler error handling for deleted active objects
We have discovered that the active object ConnectionStarter could potentially leave after deleteing itself in RunL. If that were to happen, QtRRActiveScheduler::RunMarkedIfReady would have crashed when it asked the deleted active object to handle the error. Some active object deletion detection has been added to QtRRActiveScheduler::RunMarkedIfReady to protect against crashes. The ConnectionStarter active object has been modified so that even if it does leave, when running in CActiveScheduler, it still won't cause a crash and will clean itself up correctly. Task-number: ou1cimx1#979241 Change-Id: Iafa10b96bbd8bedfec82d6d546c7ffaf0557fd8b Reviewed-by: Shane Kearns <ext-shane.2.kearns@nokia.com>
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp8
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp6
2 files changed, 10 insertions, 4 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 5d7c59c..f209b7a 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -843,8 +843,12 @@ QtRRActiveScheduler::RunResult QtRRActiveScheduler::RunMarkedIfReady(TInt &runPr
dataAccess->iStatus.iFlags&=~TRequestStatusAccess::ERequestActiveFlags;
int vptr = *(int*)active; // vptr can be used to identify type when debugging leaves
TRAP(error, QT_TRYCATCH_LEAVING(active->RunL()));
- if (error!=KErrNone)
- error=active->RunError(error);
+ if (error!=KErrNone) {
+ if (vptr != *(int*)active)
+ qWarning("Active object vptr change from 0x%08x to 0x%08x. Error %i not handled.", vptr, *(int*)active, error);
+ else
+ error=active->RunError(error);
+ }
if (error) {
qWarning("Active object (ptr=0x%08x, vptr=0x%08x) leave: %i\n", active, vptr, error);
dispatcher->activeObjectError(error);
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 9f6d08d..fbf21fa 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -1050,7 +1050,7 @@ void QNetworkSessionPrivateImpl::ConnectionStartComplete(TInt statusCode)
qDebug() << "QNS this : " << QString::number((uint)this) << " - "
<< "RConnection::Start completed with status code: " << statusCode;
#endif
- delete ipConnectionStarter;
+ // ConnectionStarter *ipConnectionStarter will delete itself at the end of RunL
ipConnectionStarter = 0;
switch (statusCode) {
@@ -1572,12 +1572,14 @@ void ConnectionStarter::Start(TConnPref &pref)
void ConnectionStarter::RunL()
{
iOwner.ConnectionStartComplete(iStatus.Int());
- //note owner deletes on callback
+ delete this;
}
TInt ConnectionStarter::RunError(TInt err)
{
qWarning() << "ConnectionStarter::RunError" << err;
+ // there must have been a leave from iOwner.ConnectionStartComplete, in which case "delete this" in RunL was missed.
+ delete this;
return KErrNone;
}