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"))); |