--- a/vpnengine/sit/src/taskarrivalobserver.cpp Wed Sep 15 13:20:54 2010 +0300
+++ b/vpnengine/sit/src/taskarrivalobserver.cpp Wed Oct 13 15:42:16 2010 +0300
@@ -33,6 +33,7 @@
}
CTaskArrivalObserver::CTaskArrivalObserver()
+ : CAsyncOneShot(EPriorityNormal)
{
}
@@ -48,9 +49,8 @@
LOG(Log::Printf(_L("CTaskArrivalObserver::~CTaskArrivalObserver\n")));
Cancel();
iEventMediator.Close();
-
if (iTaskHandlerList)
- {
+ {
iTaskHandlerList->ResetAndDestroy();
delete iTaskHandlerList;
}
@@ -116,25 +116,62 @@
{
LOG(Log::Printf(_L("CTaskArrivalObserver::LaunchTaskHandlerL\n")));
// A new task has arrived so create a task handler for it
+ CTaskHandler* taskHandler = CreateTaskHandlerL(aEventSpec);
- CTaskHandler* taskHandler = TaskHandlerCreator::CreateTaskHandlerL(this, aEventSpec);
+ // Add the handler to the list of active handlers
+ iTaskHandlerList->AppendL(taskHandler);
+
+ // And start performing the task
+ taskHandler->Start();
+ }
+
+CTaskHandler* CTaskArrivalObserver::CreateTaskHandlerL(const TTaskArrivedEventData& aEventSpec)
+ {
+ LOG(Log::Printf(_L("CTaskArrivalObserver::CreateTaskHandlerL\n")));
+ CTaskHandler* taskHandler = NULL;
+
+ taskHandler = TaskHandlerCreator::CreateTaskHandlerL(this, aEventSpec);
+
if (!taskHandler)
{
User::Panic(KSitName, EPanicUnknownEventType);
}
-
- // Add the handler to the list of active handlers
- iTaskHandlerList->AppendL(taskHandler);
+
+ return taskHandler;
+ }
- //Create the asyncleaner for cleaning the task handler, when the
- //task is done.
- CAsyncCleaner* asyncCleaner = new (ELeave) CAsyncCleaner(this, taskHandler);
- iAsyncCleanerList->AppendL(asyncCleaner);
-
- // And start performing the task
- taskHandler->Start();
+TInt CTaskArrivalObserver::FindTaskHandler(CTaskHandler* aTaskHandler)
+ {
+ TInt foundIndex = KUnfoundIndex;
+
+ for (TInt i = 0; i < iTaskHandlerList->Count(); i++)
+ {
+ if (iTaskHandlerList->At(i) == aTaskHandler)
+ {
+ foundIndex = i;
+ break;
+ };
+ }
+
+ return foundIndex;
}
+TInt CTaskArrivalObserver::FindAsyncCleaner(CAsyncCleaner* aAsyncCleaner)
+ {
+ TInt foundIndex = KUnfoundIndex;
+
+ for (TInt i = 0; i < iAsyncCleanerList->Count(); i++)
+ {
+ if (iAsyncCleanerList->At(i) == aAsyncCleaner)
+ {
+ foundIndex = i;
+ break;
+ };
+ }
+
+ return foundIndex;
+ }
+
void CTaskArrivalObserver::TaskHandlerComplete(CTaskHandler* aTaskHandler)
{
LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerComplete\n")));
@@ -144,73 +181,98 @@
// Otherwise we'll get panic E32USER-CBase 42 (SetActive called
// while active object is already active).
- //Find the async cleaner for the task handler:
- TInt i = 0;
- for (i = 0; i < iAsyncCleanerList->Count(); ++i)
+ // NOTE. Each asyncCleaner instance will cause itself to be deleted
+ CAsyncCleaner* asyncCleaner = new CAsyncCleaner(this, aTaskHandler);
+ if (asyncCleaner)
+ {
+ // Add the handler to a list of cleaners. This list
+ // is needed to handle some rare cases where the SIT
+ // thread dies before one or more async cleaners get
+ // the chance to delete themselves. Such cleaner
+ // instances get destroyed by the CTaskArrivalObserver
+ // destructor.
+ TRAP_IGNORE(iAsyncCleanerList->AppendL(asyncCleaner));
+ // Initiate the task handler delete operation
+ asyncCleaner->Start();
+ }
+ else
{
- if (iAsyncCleanerList->At(i)->IsMatchingCleaner(*aTaskHandler))
- {
- iAsyncCleanerList->At(i)->Start();
- }
+ // Backup - just in case asyncCleaner could not be created
+ AsyncDeleteTaskHandler(aTaskHandler);
}
- __ASSERT_DEBUG(i <= iAsyncCleanerList->Count(), User::Invariant());
-
+ }
+
+void CTaskArrivalObserver::AsyncDeleteTaskHandler(CTaskHandler* aTaskHandler)
+ {
+ LOG(Log::Printf(_L("CTaskArrivalObserver::AsyncDeleteTaskHandler\n")));
+ iTaskHandlerToDelete = aTaskHandler;
+ Call();
+ }
+
+void CTaskArrivalObserver::RunL() // Called as a result of AsyncDeleteTaskHandler
+ {
+ LOG(Log::Printf(_L("CTaskArrivalObserver::RunL\n")));
+
+ DeleteTaskHandler(iTaskHandlerToDelete);
+
+ iTaskHandlerToDelete = NULL;
}
void CTaskArrivalObserver::DeleteTaskHandler(CTaskHandler* aTaskHandler)
{
LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler\n")));
- __ASSERT_DEBUG(aTaskHandler != NULL, User::Invariant());
-
// The specified task handler has done its
// job succesfully so it can be deleted
- TInt taskHandlerIndex = KErrNotFound;
-
- for (TInt i = 0; i < iTaskHandlerList->Count(); i++)
+ TInt taskHandlerIndex = FindTaskHandler(aTaskHandler);
+
+ if (taskHandlerIndex != KUnfoundIndex)
{
- if (iTaskHandlerList->At(i) == aTaskHandler)
- {
- taskHandlerIndex = i;
- break;
- };
+ LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n")));
+ // Delete the task handler
+ delete iTaskHandlerList->At(taskHandlerIndex);
+ // Delete the list item
+ iTaskHandlerList->Delete(taskHandlerIndex);
+ // Deleting elements from the array does not cause
+ // the array buffer to be automatically compressed.
+ // Compress it to return excess space to the heap
+ // as task handlers come and go.
+ iTaskHandlerList->Compress();
}
-
- __ASSERT_DEBUG(taskHandlerIndex >= 0, User::Invariant());
-
- LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n")));
- // Delete the task handler
- delete aTaskHandler;
- iTaskHandlerList->Delete(taskHandlerIndex);
- iTaskHandlerList->Compress();
+ else
+ {
+ //
+ delete aTaskHandler;
+ }
}
void CTaskArrivalObserver::DeleteAsyncCleaner(CAsyncCleaner* aAsyncCleaner)
{
LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner\n")));
- __ASSERT_DEBUG(aAsyncCleaner != NULL, User::Invariant());
-
// The specified asynchronous cleaner
// has done its job and be deleted
+ TInt asyncCleanerIndex = FindAsyncCleaner(aAsyncCleaner);
- TInt asyncCleanerIndex = KErrNotFound;
- for (TInt i = 0; i < iAsyncCleanerList->Count(); i++)
+ if (asyncCleanerIndex != KUnfoundIndex)
{
- if (iAsyncCleanerList->At(i) == aAsyncCleaner)
- {
- asyncCleanerIndex = i;
- break;
- };
+ LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner - deleting async cleaner\n")));
+ // Delete the cleaner object
+ delete iAsyncCleanerList->At(asyncCleanerIndex);
+ // Delete the list item
+ iAsyncCleanerList->Delete(asyncCleanerIndex);
+ // Deleting elements from the array does not cause
+ // the array buffer to be automatically compressed.
+ // Compress it to return excess space to the heap
+ // as cleaner objects come and go.
+ iAsyncCleanerList->Compress();
}
-
- __ASSERT_DEBUG(asyncCleanerIndex >= 0, User::Invariant());
-
- // Delete the cleaner object
- delete aAsyncCleaner;
- iAsyncCleanerList->Delete(asyncCleanerIndex);
- iAsyncCleanerList->Compress();
-
+ else
+ {
+ // Always delete the cleaner instance even
+ // though it have not been added to the list
+ delete aAsyncCleaner;
+ }
}
void CTaskArrivalObserver::TaskHandlerFatalError(CTaskHandler* /*aTaskHandler*/, TInt /*aError*/)
@@ -248,8 +310,3 @@
// Delete this cleaner object instance as well
iTaskArrivalObserver->DeleteAsyncCleaner(this);
}
-
-TBool CAsyncCleaner::IsMatchingCleaner(const CTaskHandler& aTaskHandler) const
- {
- return iTaskHandlerToDelete == &aTaskHandler;
- }