|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Serializing the task |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <mpxlog.h> |
|
19 #include "mpxtaskqueueobserver.h" |
|
20 #include "mpxtaskqueue.h" |
|
21 |
|
22 // ============================ PRIVATE CLASS ================================= |
|
23 NONSHARABLE_CLASS(CTask) : public CBase |
|
24 { |
|
25 public: |
|
26 /** |
|
27 * C++ constructor |
|
28 * |
|
29 * @param aTask task id |
|
30 * @param aCallback callback |
|
31 * @param aHandler task handler |
|
32 * @param aParamData data |
|
33 * @param aBuf, extra data in buffer, ownership transferred. |
|
34 * @param aPtrData, extra pointer data |
|
35 * @param aAlive1, pointer to CBased object, ownership transferred |
|
36 * @param aCObject2, pointer to CBased object, ownership transferred |
|
37 */ |
|
38 CTask(TInt aTask, |
|
39 TAny* aCallback, |
|
40 MMPXTaskQueueObserver* aHandler, |
|
41 TInt aParamData=0, |
|
42 CBufBase* aBuf=NULL, |
|
43 TAny* aPtrData=NULL, |
|
44 CBase* aCObject1=NULL, |
|
45 CBase* aCObject2=NULL |
|
46 ); |
|
47 |
|
48 /** |
|
49 * destructor |
|
50 */ |
|
51 ~CTask(); |
|
52 |
|
53 /** |
|
54 * Offset to the task queue |
|
55 * |
|
56 * @return the offset |
|
57 */ |
|
58 static TInt Offset(); |
|
59 |
|
60 public: |
|
61 TInt iTask; |
|
62 TAny* iCallback; // call back when task completed |
|
63 MMPXTaskQueueObserver* iHandler; // task handler which will execute the task |
|
64 TInt iParamData; // Integer data |
|
65 CBufBase* iBuf; // owned. deleted when task is removed |
|
66 TAny* iPtrData; // ojbect data, Not owned. |
|
67 CBase* iCObject1; // owned |
|
68 CBase* iCObject2; // owned |
|
69 |
|
70 TPtrC8 iPtr; // Descriptor to iBuf |
|
71 TSglQueLink iLink; |
|
72 }; |
|
73 |
|
74 // ---------------------------------------------------------------------------- |
|
75 // Task contructor |
|
76 // ---------------------------------------------------------------------------- |
|
77 // |
|
78 CTask::CTask( |
|
79 TInt aTask, |
|
80 TAny* aCallback, |
|
81 MMPXTaskQueueObserver* aHandler, |
|
82 TInt aParamData/*=0*/, |
|
83 CBufBase* aBuf/*=NULL*/, |
|
84 TAny* aPtrData/*=NULL*/, |
|
85 CBase* aCObject1/*=NULL*/, |
|
86 CBase* aCObject2/*=NULL*/) |
|
87 : iTask(aTask), iCallback(aCallback), iHandler(aHandler), |
|
88 iParamData(aParamData),iBuf(aBuf), iPtrData(aPtrData), |
|
89 iCObject1(aCObject1),iCObject2(aCObject2) |
|
90 { |
|
91 if (iBuf) |
|
92 { |
|
93 iPtr.Set(iBuf->Ptr(0)); |
|
94 } |
|
95 else |
|
96 { |
|
97 iPtr.Set(KNullDesC8); |
|
98 } |
|
99 } |
|
100 |
|
101 // ---------------------------------------------------------------------------- |
|
102 // Task destructor |
|
103 // ---------------------------------------------------------------------------- |
|
104 // |
|
105 CTask::~CTask() |
|
106 { |
|
107 delete iBuf; |
|
108 delete iCObject1; |
|
109 delete iCObject2; |
|
110 } |
|
111 |
|
112 // ---------------------------------------------------------------------------- |
|
113 // Offset of the task queue |
|
114 // ---------------------------------------------------------------------------- |
|
115 // |
|
116 TInt CTask::Offset() |
|
117 { |
|
118 return _FOFF(CTask,iLink); |
|
119 } |
|
120 |
|
121 // ============================ PRIVATE CLASS ================================= |
|
122 NONSHARABLE_CLASS(CMPXTaskQueueScheduler) : public CActive |
|
123 { |
|
124 public: |
|
125 /** |
|
126 * Two-phased constructor |
|
127 * @param aObserver the observer |
|
128 * @return object of constructed |
|
129 */ |
|
130 static CMPXTaskQueueScheduler* NewL(TSglQue<CTask>& aTaskQueue); |
|
131 |
|
132 /** |
|
133 * Destructor |
|
134 */ |
|
135 ~CMPXTaskQueueScheduler(); |
|
136 |
|
137 /** |
|
138 * Schedule to execute next task |
|
139 */ |
|
140 void ScheduleNextTask(); |
|
141 |
|
142 /** |
|
143 * Complete current task |
|
144 */ |
|
145 void CompleteTask(); |
|
146 |
|
147 public: // From base classes |
|
148 |
|
149 /** |
|
150 * From CActive |
|
151 * Handles an active object's request completion event |
|
152 */ |
|
153 void RunL(); |
|
154 |
|
155 /** |
|
156 * From CActive |
|
157 * Implements cancellation of an outstanding request. |
|
158 */ |
|
159 void DoCancel(); |
|
160 |
|
161 private: |
|
162 /** |
|
163 * C++ constructor |
|
164 * |
|
165 * @param aObserver observer |
|
166 */ |
|
167 CMPXTaskQueueScheduler(TSglQue<CTask>& aTaskQueue); |
|
168 |
|
169 /** |
|
170 * 2nd phase contructor |
|
171 * |
|
172 */ |
|
173 void ConstructL(); |
|
174 |
|
175 private: |
|
176 TSglQue<CTask>& iTaskQueue; |
|
177 TBool iTaskProcessing; |
|
178 }; |
|
179 |
|
180 // ---------------------------------------------------------------------------- |
|
181 // Two-phased constructor |
|
182 // ---------------------------------------------------------------------------- |
|
183 // |
|
184 CMPXTaskQueueScheduler* CMPXTaskQueueScheduler::NewL(TSglQue<CTask>& aTaskQueue) |
|
185 { |
|
186 CMPXTaskQueueScheduler* s = new(ELeave)CMPXTaskQueueScheduler(aTaskQueue); |
|
187 CleanupStack::PushL(s); |
|
188 s->ConstructL(); |
|
189 CleanupStack::Pop(s); |
|
190 return s; |
|
191 } |
|
192 |
|
193 // ---------------------------------------------------------------------------- |
|
194 // Constructor. |
|
195 // ---------------------------------------------------------------------------- |
|
196 // |
|
197 CMPXTaskQueueScheduler::CMPXTaskQueueScheduler(TSglQue<CTask>& aTaskQueue) |
|
198 :CActive(EPriorityStandard), |
|
199 iTaskQueue(aTaskQueue), |
|
200 iTaskProcessing(EFalse) |
|
201 { |
|
202 CActiveScheduler::Add(this); |
|
203 } |
|
204 |
|
205 // ---------------------------------------------------------------------------- |
|
206 // Constructor. |
|
207 // ---------------------------------------------------------------------------- |
|
208 // |
|
209 void CMPXTaskQueueScheduler::ConstructL() |
|
210 { |
|
211 } |
|
212 |
|
213 // ---------------------------------------------------------------------------- |
|
214 // Destructor |
|
215 // ---------------------------------------------------------------------------- |
|
216 // |
|
217 CMPXTaskQueueScheduler::~CMPXTaskQueueScheduler() |
|
218 { |
|
219 Cancel(); |
|
220 } |
|
221 |
|
222 // ---------------------------------------------------------------------------- |
|
223 // Schedule to execute next task |
|
224 // ---------------------------------------------------------------------------- |
|
225 // |
|
226 void CMPXTaskQueueScheduler::ScheduleNextTask() |
|
227 { |
|
228 if (!IsActive() && !iTaskProcessing) |
|
229 { |
|
230 SetActive(); |
|
231 TRequestStatus* status = &iStatus; |
|
232 User::RequestComplete(status, KErrNone); |
|
233 } |
|
234 } |
|
235 |
|
236 // ---------------------------------------------------------------------------- |
|
237 // Complete current task |
|
238 // ---------------------------------------------------------------------------- |
|
239 // |
|
240 void CMPXTaskQueueScheduler::CompleteTask() |
|
241 { |
|
242 iTaskProcessing = EFalse; |
|
243 } |
|
244 |
|
245 // ---------------------------------------------------------------------------- |
|
246 // Plugin has completed the request |
|
247 // ---------------------------------------------------------------------------- |
|
248 // |
|
249 void CMPXTaskQueueScheduler::RunL() |
|
250 { |
|
251 MPX_FUNC_EX("CMPXTaskQueueScheduler::RunL"); |
|
252 if (!iTaskQueue.IsEmpty()) |
|
253 { |
|
254 CTask* task=iTaskQueue.First(); |
|
255 if (task->iHandler) |
|
256 { |
|
257 iTaskProcessing = ETrue; |
|
258 MPX_DEBUG3("CMPXTaskQueueScheduler::RunL %d cb 0x%08x", |
|
259 task->iTask, task->iCallback); |
|
260 task->iHandler->ExecuteTask(task->iTask, |
|
261 task->iParamData, |
|
262 task->iPtrData, |
|
263 *(task->iBuf), |
|
264 task->iCallback, |
|
265 task->iCObject1, |
|
266 task->iCObject2); |
|
267 } |
|
268 } |
|
269 } |
|
270 |
|
271 // ---------------------------------------------------------------------------- |
|
272 // Canceling has to be done by plugin |
|
273 // ---------------------------------------------------------------------------- |
|
274 // |
|
275 void CMPXTaskQueueScheduler::DoCancel() |
|
276 { |
|
277 iTaskProcessing = EFalse; |
|
278 } |
|
279 |
|
280 |
|
281 // ============================ MEMBER FUNCTIONS ============================== |
|
282 |
|
283 // ---------------------------------------------------------------------------- |
|
284 // Two-phased constructor |
|
285 // ---------------------------------------------------------------------------- |
|
286 // |
|
287 EXPORT_C CMPXTaskQueue* CMPXTaskQueue::NewL() |
|
288 { |
|
289 CMPXTaskQueue* s = new(ELeave)CMPXTaskQueue(); |
|
290 CleanupStack::PushL(s); |
|
291 s->ConstructL(); |
|
292 CleanupStack::Pop(s); |
|
293 return s; |
|
294 } |
|
295 |
|
296 // ---------------------------------------------------------------------------- |
|
297 // Constructor. |
|
298 // ---------------------------------------------------------------------------- |
|
299 // |
|
300 CMPXTaskQueue::CMPXTaskQueue() |
|
301 :iTaskList(CTask::Offset()) |
|
302 { |
|
303 } |
|
304 |
|
305 // ---------------------------------------------------------------------------- |
|
306 // Destructor |
|
307 // ---------------------------------------------------------------------------- |
|
308 // |
|
309 EXPORT_C CMPXTaskQueue::~CMPXTaskQueue() |
|
310 { |
|
311 Reset(); |
|
312 } |
|
313 |
|
314 // ---------------------------------------------------------------------------- |
|
315 // Constructor. |
|
316 // ---------------------------------------------------------------------------- |
|
317 // |
|
318 void CMPXTaskQueue::ConstructL() |
|
319 { |
|
320 } |
|
321 |
|
322 |
|
323 // ---------------------------------------------------------------------------- |
|
324 // Add a task |
|
325 // ---------------------------------------------------------------------------- |
|
326 // |
|
327 EXPORT_C void CMPXTaskQueue::AddTaskL( |
|
328 TInt aTask, |
|
329 TAny* aCallback, |
|
330 TInt aParamData/*=0*/, |
|
331 CBufBase* aBuf/*=NULL*/, |
|
332 TAny* aPtrData/*=NULL*/, |
|
333 CBase* aCObject1/*=NULL*/, |
|
334 CBase* aCObject2/*=NULL*/) |
|
335 { |
|
336 MPX_FUNC_EX("CMPXTaskQueue::AddTaskL"); |
|
337 CTask* t=new(ELeave)CTask(aTask,aCallback,NULL, aParamData, |
|
338 aBuf, aPtrData,aCObject1,aCObject2); |
|
339 iTaskList.AddLast(*t); |
|
340 } |
|
341 |
|
342 // ---------------------------------------------------------------------------- |
|
343 // Remove a task |
|
344 // ---------------------------------------------------------------------------- |
|
345 // |
|
346 EXPORT_C TAny* CMPXTaskQueue::RemoveTask() |
|
347 { |
|
348 MPX_FUNC_EX("CMPXTaskQueue::RemoveTask()"); |
|
349 // Remove current task from queque |
|
350 if (iTaskList.IsEmpty()) |
|
351 { |
|
352 return NULL; |
|
353 } |
|
354 CTask* task=iTaskList.First(); |
|
355 TAny* cb=task->iCallback; |
|
356 iTaskList.Remove(*task); |
|
357 MPX_DEBUG3("CMPXTaskQueue::RemoveTask %d cb 0x%08x", task->iTask, cb); |
|
358 delete task; |
|
359 return cb; |
|
360 } |
|
361 |
|
362 // ---------------------------------------------------------------------------- |
|
363 // Remove task from a client |
|
364 // ---------------------------------------------------------------------------- |
|
365 // |
|
366 EXPORT_C void CMPXTaskQueue::RemoveTask(TAny* aCallback) |
|
367 { |
|
368 MPX_FUNC_EX("CMPXTaskQueue::RemoveTask(TAny* aCallback)"); |
|
369 // Remove current task from queque |
|
370 TSglQueIter<CTask> iter(iTaskList); |
|
371 CTask* t=NULL; |
|
372 while ((t=iter++) != NULL) // Compiler warning on while (t=iter++) |
|
373 { |
|
374 if (t->iCallback == aCallback) |
|
375 { |
|
376 iTaskList.Remove(*t); |
|
377 MPX_DEBUG3("CMPXTaskQueue::RemoveTask %d cb 0x%08x", |
|
378 t->iTask, aCallback); |
|
379 delete t; |
|
380 } |
|
381 } |
|
382 } |
|
383 |
|
384 // ---------------------------------------------------------------------------- |
|
385 // Reutrn if the task queue empty |
|
386 // ---------------------------------------------------------------------------- |
|
387 // |
|
388 EXPORT_C TBool CMPXTaskQueue::IsEmpty() |
|
389 { |
|
390 return iTaskList.IsEmpty(); |
|
391 } |
|
392 |
|
393 // ---------------------------------------------------------------------------- |
|
394 // Reset task queue |
|
395 // ---------------------------------------------------------------------------- |
|
396 // |
|
397 EXPORT_C void CMPXTaskQueue::Reset() |
|
398 { |
|
399 TSglQueIter<CTask> iter(iTaskList); |
|
400 CTask* t=NULL; |
|
401 while ((t=iter++) != NULL) // Compiler warning on while (t=iter++) |
|
402 { |
|
403 delete t; |
|
404 } |
|
405 iTaskList.Reset(); |
|
406 } |
|
407 |
|
408 // ---------------------------------------------------------------------------- |
|
409 // Return current task |
|
410 // ---------------------------------------------------------------------------- |
|
411 // |
|
412 EXPORT_C TInt CMPXTaskQueue::Param() |
|
413 { |
|
414 return iTaskList.IsEmpty() ? KErrNotFound : iTaskList.First()->iParamData; |
|
415 } |
|
416 |
|
417 // ---------------------------------------------------------------------------- |
|
418 // Return current parameter data |
|
419 // ---------------------------------------------------------------------------- |
|
420 // |
|
421 EXPORT_C TInt CMPXTaskQueue::Task() |
|
422 { |
|
423 return iTaskList.IsEmpty() ? KErrNotFound : iTaskList.First()->iTask; |
|
424 } |
|
425 |
|
426 // ---------------------------------------------------------------------------- |
|
427 // Return current call back |
|
428 // ---------------------------------------------------------------------------- |
|
429 // |
|
430 EXPORT_C TAny* CMPXTaskQueue::Callback() |
|
431 { |
|
432 return iTaskList.IsEmpty() ? NULL : iTaskList.First()->iCallback; |
|
433 } |
|
434 |
|
435 // ---------------------------------------------------------------------------- |
|
436 // Return pointer data |
|
437 // ---------------------------------------------------------------------------- |
|
438 // |
|
439 EXPORT_C TAny* CMPXTaskQueue::PtrData() |
|
440 { |
|
441 return iTaskList.IsEmpty() ? NULL : iTaskList.First()->iPtrData; |
|
442 } |
|
443 |
|
444 // ---------------------------------------------------------------------------- |
|
445 // Return buffer data |
|
446 // ---------------------------------------------------------------------------- |
|
447 // |
|
448 EXPORT_C const TDesC8& CMPXTaskQueue::BufData() |
|
449 { |
|
450 if (iTaskList.IsEmpty()) |
|
451 { |
|
452 return KNullDesC8; |
|
453 } |
|
454 else |
|
455 { |
|
456 return iTaskList.First()->iPtr; |
|
457 } |
|
458 } |
|
459 |
|
460 // ---------------------------------------------------------------------------- |
|
461 // Two-phased constructor |
|
462 // ---------------------------------------------------------------------------- |
|
463 // |
|
464 EXPORT_C CMPXActiveTaskQueue* CMPXActiveTaskQueue::NewL() |
|
465 { |
|
466 CMPXActiveTaskQueue* s = new(ELeave)CMPXActiveTaskQueue(); |
|
467 CleanupStack::PushL(s); |
|
468 s->ConstructL(); |
|
469 CleanupStack::Pop(s); |
|
470 return s; |
|
471 } |
|
472 |
|
473 // ---------------------------------------------------------------------------- |
|
474 // Constructor. |
|
475 // ---------------------------------------------------------------------------- |
|
476 // |
|
477 CMPXActiveTaskQueue::CMPXActiveTaskQueue() |
|
478 { |
|
479 } |
|
480 |
|
481 // ---------------------------------------------------------------------------- |
|
482 // Constructor. |
|
483 // ---------------------------------------------------------------------------- |
|
484 // |
|
485 void CMPXActiveTaskQueue::ConstructL() |
|
486 { |
|
487 iScheduler = CMPXTaskQueueScheduler::NewL(iTaskList); |
|
488 } |
|
489 |
|
490 |
|
491 // ---------------------------------------------------------------------------- |
|
492 // Destructor |
|
493 // ---------------------------------------------------------------------------- |
|
494 // |
|
495 EXPORT_C CMPXActiveTaskQueue::~CMPXActiveTaskQueue() |
|
496 { |
|
497 MPX_FUNC_EX("CMPXActiveTaskQueue::~CMPXActiveTaskQueue"); |
|
498 if (iScheduler) |
|
499 { |
|
500 delete iScheduler; |
|
501 } |
|
502 } |
|
503 |
|
504 // ---------------------------------------------------------------------------- |
|
505 // Add a task |
|
506 // ---------------------------------------------------------------------------- |
|
507 // |
|
508 EXPORT_C void CMPXActiveTaskQueue::AddTaskL( |
|
509 TInt aTask, |
|
510 TAny* aCallback, |
|
511 MMPXTaskQueueObserver* aHandler, |
|
512 TInt aParamData/*=0*/, |
|
513 CBufBase* aBuf/*=NULL*/, |
|
514 TAny* aPtrData/*=NULL*/, |
|
515 CBase* aCObject1/*=NULL*/, |
|
516 CBase* aCObject2/*=NULL*/) |
|
517 { |
|
518 MPX_FUNC_EX("CMPXActiveTaskQueue::AddTaskL"); |
|
519 CTask* t=new(ELeave)CTask(aTask,aCallback,aHandler,aParamData, |
|
520 aBuf,aPtrData,aCObject1,aCObject2); |
|
521 iTaskList.AddLast(*t); |
|
522 ScheduleNextTask(); |
|
523 } |
|
524 |
|
525 // ---------------------------------------------------------------------------- |
|
526 // Schedule to execute next task |
|
527 // ---------------------------------------------------------------------------- |
|
528 // |
|
529 EXPORT_C void CMPXActiveTaskQueue::ScheduleNextTask() |
|
530 { |
|
531 iScheduler->ScheduleNextTask(); |
|
532 } |
|
533 |
|
534 // ---------------------------------------------------------------------------- |
|
535 // Complete current task |
|
536 // ---------------------------------------------------------------------------- |
|
537 // |
|
538 EXPORT_C void CMPXActiveTaskQueue::CompleteTask() |
|
539 { |
|
540 MPX_FUNC_EX("CMPXActiveTaskQueue::CompleteTask()"); |
|
541 (void)RemoveTask(); |
|
542 iScheduler->CompleteTask(); |
|
543 ScheduleNextTask(); |
|
544 } |
|
545 |
|
546 // ---------------------------------------------------------------------------- |
|
547 // Cancels all outsatnding tasks |
|
548 // ---------------------------------------------------------------------------- |
|
549 // |
|
550 EXPORT_C void CMPXActiveTaskQueue::CancelRequests() |
|
551 { |
|
552 MPX_FUNC_EX("CMPXActiveTaskQueue::CancelRequests"); |
|
553 iScheduler->Cancel(); |
|
554 CMPXTaskQueue::Reset(); |
|
555 } |
|
556 |
|
557 // ---------------------------------------------------------------------------- |
|
558 // CMPXActiveTaskQueue::CompleteAllTasks |
|
559 // ---------------------------------------------------------------------------- |
|
560 // |
|
561 EXPORT_C void CMPXActiveTaskQueue::CompleteAllTasks( |
|
562 TInt aError) |
|
563 { |
|
564 MPX_FUNC_EX("CMPXActiveTaskQueue::CompleteAllTasks"); |
|
565 iScheduler->Cancel(); |
|
566 |
|
567 TSglQueIter<CTask> iter(iTaskList); |
|
568 CTask* task(NULL); |
|
569 while ((task = iter++) != NULL) // Compiler warning on while (t=iter++) |
|
570 { |
|
571 task->iHandler->HandleTaskError(task->iTask, task->iPtrData, |
|
572 task->iCallback, aError); |
|
573 delete task; |
|
574 } |
|
575 iTaskList.Reset(); |
|
576 } |