vpnengine/sit/src/taskarrivalobserver.cpp
branchRCL_3
changeset 44 735de8341ce4
parent 0 33413c0669b9
child 49 5960d2d03390
equal deleted inserted replaced
41:e06095241a65 44:735de8341ce4
    31     LOG(Log::Printf(_L("CTaskArrivalObserver::NewL - end\n")));
    31     LOG(Log::Printf(_L("CTaskArrivalObserver::NewL - end\n")));
    32     return self;
    32     return self;
    33     }
    33     }
    34     
    34     
    35 CTaskArrivalObserver::CTaskArrivalObserver()
    35 CTaskArrivalObserver::CTaskArrivalObserver()
    36     : CAsyncOneShot(EPriorityNormal)
       
    37     {
    36     {
    38     }
    37     }
    39 
    38 
    40 void CTaskArrivalObserver::ConstructL()
    39 void CTaskArrivalObserver::ConstructL()
    41     {
    40     {
    47 CTaskArrivalObserver::~CTaskArrivalObserver()
    46 CTaskArrivalObserver::~CTaskArrivalObserver()
    48     {
    47     {
    49     LOG(Log::Printf(_L("CTaskArrivalObserver::~CTaskArrivalObserver\n")));
    48     LOG(Log::Printf(_L("CTaskArrivalObserver::~CTaskArrivalObserver\n")));
    50     Cancel();
    49     Cancel();
    51     iEventMediator.Close();
    50     iEventMediator.Close();
       
    51     
    52     if (iTaskHandlerList)
    52     if (iTaskHandlerList)
    53         {
    53         {    
    54         iTaskHandlerList->ResetAndDestroy();
    54         iTaskHandlerList->ResetAndDestroy();
    55         delete iTaskHandlerList;
    55         delete iTaskHandlerList;
    56         }
    56         }
    57     if (iAsyncCleanerList)
    57     if (iAsyncCleanerList)
    58         {
    58         {
   114 
   114 
   115 void CTaskArrivalObserver::LaunchTaskHandlerL(const TTaskArrivedEventData& aEventSpec)
   115 void CTaskArrivalObserver::LaunchTaskHandlerL(const TTaskArrivedEventData& aEventSpec)
   116     {
   116     {
   117     LOG(Log::Printf(_L("CTaskArrivalObserver::LaunchTaskHandlerL\n")));
   117     LOG(Log::Printf(_L("CTaskArrivalObserver::LaunchTaskHandlerL\n")));
   118     // A new task has arrived so create a task handler for it
   118     // A new task has arrived so create a task handler for it
   119     CTaskHandler* taskHandler = CreateTaskHandlerL(aEventSpec);
   119 
   120 
   120     CTaskHandler* taskHandler = TaskHandlerCreator::CreateTaskHandlerL(this, aEventSpec);
       
   121     if (!taskHandler)
       
   122         {
       
   123         User::Panic(KSitName, EPanicUnknownEventType);
       
   124         }
       
   125         
   121     // Add the handler to the list of active handlers
   126     // Add the handler to the list of active handlers
   122     iTaskHandlerList->AppendL(taskHandler);
   127     iTaskHandlerList->AppendL(taskHandler);
   123 
   128 
       
   129     //Create the asyncleaner for cleaning the task handler, when the
       
   130     //task is done.
       
   131     CAsyncCleaner* asyncCleaner = new (ELeave) CAsyncCleaner(this, taskHandler);    
       
   132     iAsyncCleanerList->AppendL(asyncCleaner);
       
   133        
   124     // And start performing the task
   134     // And start performing the task
   125     taskHandler->Start();
   135     taskHandler->Start();
   126     }
   136     }
   127 
   137     
   128 CTaskHandler* CTaskArrivalObserver::CreateTaskHandlerL(const TTaskArrivedEventData& aEventSpec)
       
   129     {
       
   130     LOG(Log::Printf(_L("CTaskArrivalObserver::CreateTaskHandlerL\n")));
       
   131     CTaskHandler* taskHandler = NULL;
       
   132 
       
   133     taskHandler = TaskHandlerCreator::CreateTaskHandlerL(this, aEventSpec);
       
   134 
       
   135     if (!taskHandler)
       
   136         {
       
   137         User::Panic(KSitName, EPanicUnknownEventType);
       
   138         }
       
   139 
       
   140     return taskHandler;
       
   141     }
       
   142 
       
   143 TInt CTaskArrivalObserver::FindTaskHandler(CTaskHandler* aTaskHandler)
       
   144     {
       
   145     TInt foundIndex = KUnfoundIndex;
       
   146     
       
   147     for (TInt i = 0; i < iTaskHandlerList->Count(); i++)
       
   148         {
       
   149         if (iTaskHandlerList->At(i) == aTaskHandler)
       
   150             {
       
   151             foundIndex = i;
       
   152             break;
       
   153             };
       
   154         }
       
   155 
       
   156     return foundIndex;
       
   157     }
       
   158     
       
   159 TInt CTaskArrivalObserver::FindAsyncCleaner(CAsyncCleaner* aAsyncCleaner)
       
   160     {
       
   161     TInt foundIndex = KUnfoundIndex;
       
   162     
       
   163     for (TInt i = 0; i < iAsyncCleanerList->Count(); i++)
       
   164         {
       
   165         if (iAsyncCleanerList->At(i) == aAsyncCleaner)
       
   166             {
       
   167             foundIndex = i;
       
   168             break;
       
   169             };
       
   170         }
       
   171 
       
   172     return foundIndex;
       
   173     }
       
   174 
       
   175 void CTaskArrivalObserver::TaskHandlerComplete(CTaskHandler* aTaskHandler)
   138 void CTaskArrivalObserver::TaskHandlerComplete(CTaskHandler* aTaskHandler)
   176     {
   139     {
   177     LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerComplete\n")));
   140     LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerComplete\n")));
   178 
   141 
   179     // In the case several task handlers delete themselves at about the
   142     // In the case several task handlers delete themselves at about the
   180     // same time, we need to have a separate cleaner instance for each.
   143     // same time, we need to have a separate cleaner instance for each.
   181     // Otherwise we'll get panic E32USER-CBase 42 (SetActive called
   144     // Otherwise we'll get panic E32USER-CBase 42 (SetActive called
   182     // while active object is already active).
   145     // while active object is already active).
   183     
   146     
   184     // NOTE. Each asyncCleaner instance will cause itself to be deleted
   147     //Find the async cleaner for the task handler:
   185     CAsyncCleaner* asyncCleaner = new CAsyncCleaner(this, aTaskHandler);
   148     TInt i = 0;
   186     if (asyncCleaner)
   149     for (i = 0; i < iAsyncCleanerList->Count(); ++i)
   187         {
   150         {
   188         // Add the handler to a list of cleaners. This list
   151         if (iAsyncCleanerList->At(i)->IsMatchingCleaner(*aTaskHandler))
   189         // is needed to handle some rare cases where the SIT
   152             {
   190         // thread dies before one or more async cleaners get
   153             iAsyncCleanerList->At(i)->Start();
   191         // the chance to delete themselves. Such cleaner
   154             }
   192         // instances get destroyed by the CTaskArrivalObserver
   155         }
   193         // destructor.
   156     __ASSERT_DEBUG(i <= iAsyncCleanerList->Count(), User::Invariant());
   194         TRAP_IGNORE(iAsyncCleanerList->AppendL(asyncCleaner));
   157     
   195         // Initiate the task handler delete operation
       
   196         asyncCleaner->Start();
       
   197         }
       
   198     else
       
   199         {
       
   200         // Backup - just in case asyncCleaner could not be created
       
   201         AsyncDeleteTaskHandler(aTaskHandler);
       
   202         }
       
   203     }
       
   204 
       
   205 void CTaskArrivalObserver::AsyncDeleteTaskHandler(CTaskHandler* aTaskHandler)
       
   206     {
       
   207     LOG(Log::Printf(_L("CTaskArrivalObserver::AsyncDeleteTaskHandler\n")));
       
   208     iTaskHandlerToDelete = aTaskHandler;
       
   209     Call();
       
   210     }
       
   211 
       
   212 void CTaskArrivalObserver::RunL() // Called as a result of AsyncDeleteTaskHandler
       
   213     {
       
   214     LOG(Log::Printf(_L("CTaskArrivalObserver::RunL\n")));
       
   215 
       
   216     DeleteTaskHandler(iTaskHandlerToDelete);
       
   217 
       
   218     iTaskHandlerToDelete = NULL;    
       
   219     }
   158     }
   220 
   159 
   221 void CTaskArrivalObserver::DeleteTaskHandler(CTaskHandler* aTaskHandler)
   160 void CTaskArrivalObserver::DeleteTaskHandler(CTaskHandler* aTaskHandler)
   222     {
   161     {
   223     LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler\n")));
   162     LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler\n")));
   224     
   163     
       
   164     __ASSERT_DEBUG(aTaskHandler != NULL, User::Invariant());
       
   165      
   225     // The specified task handler has done its
   166     // The specified task handler has done its
   226     // job succesfully so it can be deleted
   167     // job succesfully so it can be deleted
   227     TInt taskHandlerIndex = FindTaskHandler(aTaskHandler);
   168     TInt taskHandlerIndex = KErrNotFound;
   228     
   169         
   229     if (taskHandlerIndex != KUnfoundIndex)
   170     for (TInt i = 0; i < iTaskHandlerList->Count(); i++)
   230         {
   171         {
   231         LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n")));
   172         if (iTaskHandlerList->At(i) == aTaskHandler)
   232         // Delete the task handler
   173             {
   233         delete iTaskHandlerList->At(taskHandlerIndex);
   174             taskHandlerIndex = i;
   234         // Delete the list item
   175             break;
   235         iTaskHandlerList->Delete(taskHandlerIndex);
   176             };
   236         // Deleting elements from the array does not cause
   177         }
   237         // the array buffer to be automatically compressed.
   178     
   238         // Compress it to return excess space to the heap
   179     __ASSERT_DEBUG(taskHandlerIndex >= 0, User::Invariant());
   239         // as task handlers come and go.
   180        
   240         iTaskHandlerList->Compress();
   181     LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n")));
   241         }
   182     // Delete the task handler
   242     else
   183     delete aTaskHandler;
   243         {
   184     iTaskHandlerList->Delete(taskHandlerIndex);
   244         // 
   185     iTaskHandlerList->Compress();
   245         delete aTaskHandler;
       
   246         }
       
   247     }
   186     }
   248     
   187     
   249 void CTaskArrivalObserver::DeleteAsyncCleaner(CAsyncCleaner* aAsyncCleaner)
   188 void CTaskArrivalObserver::DeleteAsyncCleaner(CAsyncCleaner* aAsyncCleaner)
   250     {
   189     {
   251     LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner\n")));
   190     LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner\n")));
       
   191     
       
   192     __ASSERT_DEBUG(aAsyncCleaner != NULL, User::Invariant());
   252     
   193     
   253     // The specified asynchronous cleaner
   194     // The specified asynchronous cleaner
   254     // has done its job and be deleted
   195     // has done its job and be deleted
   255     TInt asyncCleanerIndex = FindAsyncCleaner(aAsyncCleaner);
   196     
   256     
   197     TInt asyncCleanerIndex = KErrNotFound;
   257     if (asyncCleanerIndex != KUnfoundIndex)
   198     for (TInt i = 0; i < iAsyncCleanerList->Count(); i++)
   258         {
   199         {
   259         LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner - deleting async cleaner\n")));
   200         if (iAsyncCleanerList->At(i) == aAsyncCleaner)
   260         // Delete the cleaner object
   201             {
   261         delete iAsyncCleanerList->At(asyncCleanerIndex);
   202             asyncCleanerIndex = i;
   262         // Delete the list item
   203             break;
   263         iAsyncCleanerList->Delete(asyncCleanerIndex);
   204             };
   264         // Deleting elements from the array does not cause
   205         }
   265         // the array buffer to be automatically compressed.
   206    
   266         // Compress it to return excess space to the heap
   207     __ASSERT_DEBUG(asyncCleanerIndex >= 0, User::Invariant());
   267         // as cleaner objects come and go.
   208     
   268         iAsyncCleanerList->Compress();
   209     // Delete the cleaner object
   269         }
   210     delete aAsyncCleaner;
   270     else
   211     iAsyncCleanerList->Delete(asyncCleanerIndex);
   271         {
   212     iAsyncCleanerList->Compress();
   272         // Always delete the cleaner instance even
   213     
   273         // though it have not been added to the list
       
   274         delete aAsyncCleaner;
       
   275         }
       
   276     }
   214     }
   277 
   215 
   278 void CTaskArrivalObserver::TaskHandlerFatalError(CTaskHandler* /*aTaskHandler*/, TInt /*aError*/)
   216 void CTaskArrivalObserver::TaskHandlerFatalError(CTaskHandler* /*aTaskHandler*/, TInt /*aError*/)
   279     {
   217     {
   280     LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerFatalError - stopping the scheduler and thus the SIT\n")));
   218     LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerFatalError - stopping the scheduler and thus the SIT\n")));
   308     iTaskArrivalObserver->DeleteTaskHandler(iTaskHandlerToDelete);
   246     iTaskArrivalObserver->DeleteTaskHandler(iTaskHandlerToDelete);
   309 
   247 
   310     // Delete this cleaner object instance as well
   248     // Delete this cleaner object instance as well
   311     iTaskArrivalObserver->DeleteAsyncCleaner(this);
   249     iTaskArrivalObserver->DeleteAsyncCleaner(this);
   312     }
   250     }
       
   251 
       
   252 TBool CAsyncCleaner::IsMatchingCleaner(const CTaskHandler& aTaskHandler) const
       
   253     {
       
   254     return iTaskHandlerToDelete == &aTaskHandler;
       
   255     }