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 |
119 CTaskHandler* taskHandler = CreateTaskHandlerL(aEventSpec); |
120 CTaskHandler* taskHandler = TaskHandlerCreator::CreateTaskHandlerL(this, aEventSpec); |
120 |
121 if (!taskHandler) |
|
122 { |
|
123 User::Panic(KSitName, EPanicUnknownEventType); |
|
124 } |
|
125 |
|
126 // Add the handler to the list of active handlers |
121 // Add the handler to the list of active handlers |
127 iTaskHandlerList->AppendL(taskHandler); |
122 iTaskHandlerList->AppendL(taskHandler); |
128 |
123 |
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 |
|
134 // And start performing the task |
124 // And start performing the task |
135 taskHandler->Start(); |
125 taskHandler->Start(); |
136 } |
126 } |
137 |
127 |
|
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 |
138 void CTaskArrivalObserver::TaskHandlerComplete(CTaskHandler* aTaskHandler) |
175 void CTaskArrivalObserver::TaskHandlerComplete(CTaskHandler* aTaskHandler) |
139 { |
176 { |
140 LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerComplete\n"))); |
177 LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerComplete\n"))); |
141 |
178 |
142 // In the case several task handlers delete themselves at about the |
179 // In the case several task handlers delete themselves at about the |
143 // same time, we need to have a separate cleaner instance for each. |
180 // same time, we need to have a separate cleaner instance for each. |
144 // Otherwise we'll get panic E32USER-CBase 42 (SetActive called |
181 // Otherwise we'll get panic E32USER-CBase 42 (SetActive called |
145 // while active object is already active). |
182 // while active object is already active). |
146 |
183 |
147 //Find the async cleaner for the task handler: |
184 // NOTE. Each asyncCleaner instance will cause itself to be deleted |
148 TInt i = 0; |
185 CAsyncCleaner* asyncCleaner = new CAsyncCleaner(this, aTaskHandler); |
149 for (i = 0; i < iAsyncCleanerList->Count(); ++i) |
186 if (asyncCleaner) |
150 { |
187 { |
151 if (iAsyncCleanerList->At(i)->IsMatchingCleaner(*aTaskHandler)) |
188 // Add the handler to a list of cleaners. This list |
152 { |
189 // is needed to handle some rare cases where the SIT |
153 iAsyncCleanerList->At(i)->Start(); |
190 // thread dies before one or more async cleaners get |
154 } |
191 // the chance to delete themselves. Such cleaner |
155 } |
192 // instances get destroyed by the CTaskArrivalObserver |
156 __ASSERT_DEBUG(i <= iAsyncCleanerList->Count(), User::Invariant()); |
193 // destructor. |
157 |
194 TRAP_IGNORE(iAsyncCleanerList->AppendL(asyncCleaner)); |
|
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; |
158 } |
219 } |
159 |
220 |
160 void CTaskArrivalObserver::DeleteTaskHandler(CTaskHandler* aTaskHandler) |
221 void CTaskArrivalObserver::DeleteTaskHandler(CTaskHandler* aTaskHandler) |
161 { |
222 { |
162 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler\n"))); |
223 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler\n"))); |
163 |
224 |
164 __ASSERT_DEBUG(aTaskHandler != NULL, User::Invariant()); |
|
165 |
|
166 // The specified task handler has done its |
225 // The specified task handler has done its |
167 // job succesfully so it can be deleted |
226 // job succesfully so it can be deleted |
168 TInt taskHandlerIndex = KErrNotFound; |
227 TInt taskHandlerIndex = FindTaskHandler(aTaskHandler); |
169 |
228 |
170 for (TInt i = 0; i < iTaskHandlerList->Count(); i++) |
229 if (taskHandlerIndex != KUnfoundIndex) |
171 { |
230 { |
172 if (iTaskHandlerList->At(i) == aTaskHandler) |
231 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n"))); |
173 { |
232 // Delete the task handler |
174 taskHandlerIndex = i; |
233 delete iTaskHandlerList->At(taskHandlerIndex); |
175 break; |
234 // Delete the list item |
176 }; |
235 iTaskHandlerList->Delete(taskHandlerIndex); |
177 } |
236 // Deleting elements from the array does not cause |
178 |
237 // the array buffer to be automatically compressed. |
179 __ASSERT_DEBUG(taskHandlerIndex >= 0, User::Invariant()); |
238 // Compress it to return excess space to the heap |
180 |
239 // as task handlers come and go. |
181 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteTaskHandler - deleting task handler\n"))); |
240 iTaskHandlerList->Compress(); |
182 // Delete the task handler |
241 } |
183 delete aTaskHandler; |
242 else |
184 iTaskHandlerList->Delete(taskHandlerIndex); |
243 { |
185 iTaskHandlerList->Compress(); |
244 // |
|
245 delete aTaskHandler; |
|
246 } |
186 } |
247 } |
187 |
248 |
188 void CTaskArrivalObserver::DeleteAsyncCleaner(CAsyncCleaner* aAsyncCleaner) |
249 void CTaskArrivalObserver::DeleteAsyncCleaner(CAsyncCleaner* aAsyncCleaner) |
189 { |
250 { |
190 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner\n"))); |
251 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner\n"))); |
191 |
|
192 __ASSERT_DEBUG(aAsyncCleaner != NULL, User::Invariant()); |
|
193 |
252 |
194 // The specified asynchronous cleaner |
253 // The specified asynchronous cleaner |
195 // has done its job and be deleted |
254 // has done its job and be deleted |
196 |
255 TInt asyncCleanerIndex = FindAsyncCleaner(aAsyncCleaner); |
197 TInt asyncCleanerIndex = KErrNotFound; |
256 |
198 for (TInt i = 0; i < iAsyncCleanerList->Count(); i++) |
257 if (asyncCleanerIndex != KUnfoundIndex) |
199 { |
258 { |
200 if (iAsyncCleanerList->At(i) == aAsyncCleaner) |
259 LOG(Log::Printf(_L("CTaskArrivalObserver::DeleteAsyncCleaner - deleting async cleaner\n"))); |
201 { |
260 // Delete the cleaner object |
202 asyncCleanerIndex = i; |
261 delete iAsyncCleanerList->At(asyncCleanerIndex); |
203 break; |
262 // Delete the list item |
204 }; |
263 iAsyncCleanerList->Delete(asyncCleanerIndex); |
205 } |
264 // Deleting elements from the array does not cause |
206 |
265 // the array buffer to be automatically compressed. |
207 __ASSERT_DEBUG(asyncCleanerIndex >= 0, User::Invariant()); |
266 // Compress it to return excess space to the heap |
208 |
267 // as cleaner objects come and go. |
209 // Delete the cleaner object |
268 iAsyncCleanerList->Compress(); |
210 delete aAsyncCleaner; |
269 } |
211 iAsyncCleanerList->Delete(asyncCleanerIndex); |
270 else |
212 iAsyncCleanerList->Compress(); |
271 { |
213 |
272 // Always delete the cleaner instance even |
|
273 // though it have not been added to the list |
|
274 delete aAsyncCleaner; |
|
275 } |
214 } |
276 } |
215 |
277 |
216 void CTaskArrivalObserver::TaskHandlerFatalError(CTaskHandler* /*aTaskHandler*/, TInt /*aError*/) |
278 void CTaskArrivalObserver::TaskHandlerFatalError(CTaskHandler* /*aTaskHandler*/, TInt /*aError*/) |
217 { |
279 { |
218 LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerFatalError - stopping the scheduler and thus the SIT\n"))); |
280 LOG(Log::Printf(_L("CTaskArrivalObserver::TaskHandlerFatalError - stopping the scheduler and thus the SIT\n"))); |