|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\euser\cbase\ub_tim.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "ub_std.h" |
|
19 |
|
20 EXPORT_C CTimer::CTimer(TInt aPriority) |
|
21 : CActive(aPriority) |
|
22 /** |
|
23 Protected constructor with priority. |
|
24 |
|
25 Use this constructor to set the priority of the active object. |
|
26 |
|
27 Classes derived from CTimer must define and provide a constructor through |
|
28 which the priority of the active object can be passed. Such a constructor |
|
29 can call CTimer's constructor in its constructor initialisation list. |
|
30 |
|
31 @param aPriority The priority of the timer. |
|
32 */ |
|
33 { |
|
34 } |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 EXPORT_C CTimer::~CTimer() |
|
40 /** |
|
41 Destructor. |
|
42 |
|
43 Frees resources prior to destruction. Specifically, it cancels any outstanding |
|
44 request and closes the RTimer handle. |
|
45 */ |
|
46 { |
|
47 |
|
48 Cancel(); |
|
49 iTimer.Close(); |
|
50 } |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 EXPORT_C void CTimer::At(const TTime &aTime) |
|
56 /** |
|
57 Requests an event at a given local time. |
|
58 |
|
59 This timer completes at the specified time - if the machine is in a |
|
60 turned off state at that time, the machine will be turned on again. |
|
61 |
|
62 Notes: |
|
63 |
|
64 1. The CTimer' RunL() function will be run as soon as possible after the |
|
65 specified system time. |
|
66 |
|
67 2. The RunL() may be delayed because the RunL() of another active object, with |
|
68 the deepest nesting-level active scheduler on the same thread, is running |
|
69 when the event occurs: this cannot be avoided, but can be minimised by |
|
70 making all RunL()s of short duration. |
|
71 |
|
72 3. The RunL() may be delayed because other, higher-priority, active objects are |
|
73 scheduled instead. This can be avoided by making CTimers very high-priority. |
|
74 |
|
75 4. The TTime object should be set to the home time. |
|
76 |
|
77 @param aTime The local time at which the event is to occur. |
|
78 |
|
79 @see TTime::HomeTime |
|
80 */ |
|
81 { |
|
82 |
|
83 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
84 iTimer.At(iStatus,aTime); |
|
85 SetActive(); |
|
86 } |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 EXPORT_C void CTimer::AtUTC(const TTime &aTimeInUTC) |
|
92 /** |
|
93 Requests an event at a given UTC time. |
|
94 |
|
95 This timer completes at the specified time - if the machine is in a |
|
96 turned off state at that time, the machine will be turned on again. |
|
97 |
|
98 Notes: |
|
99 |
|
100 1. The CTimer' RunL() function will be run as soon as possible after the |
|
101 specified system time. |
|
102 |
|
103 2. The RunL() may be delayed because the RunL() of another active object, with |
|
104 the deepest nesting-level active scheduler on the same thread, is running |
|
105 when the event occurs: this cannot be avoided, but can be minimised by |
|
106 making all RunL()s of short duration. |
|
107 |
|
108 3. The RunL() may be delayed because other, higher-priority, active objects are |
|
109 scheduled instead. This can be avoided by making CTimers very high-priority. |
|
110 |
|
111 4. The TTime object should be set to the universal time. |
|
112 |
|
113 @param aTime The UTC time at which the event is to occur. |
|
114 |
|
115 @see TTime::UniversalTime |
|
116 */ |
|
117 { |
|
118 |
|
119 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
120 iTimer.AtUTC(iStatus,aTimeInUTC); |
|
121 SetActive(); |
|
122 } |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 EXPORT_C void CTimer::After(TTimeIntervalMicroSeconds32 anInterval) |
|
128 /** |
|
129 Requests an event after an interval. |
|
130 |
|
131 This timer completes after the specified number of microseconds. The |
|
132 "after timer" counter stops during power-down. Therefore, a 5-second timer |
|
133 will complete late if the machine is turned off 2 seconds after the request |
|
134 is made. |
|
135 |
|
136 Notes: |
|
137 |
|
138 1. The CTimer's RunL() function will be run as soon as possible after the |
|
139 specified interval. |
|
140 |
|
141 2. The RunL() may be delayed because the RunL() of another active object, with |
|
142 the deepest nesting-level active scheduler on the same thread, is running |
|
143 when the event occurs: this cannot be avoided, but can be minimised by |
|
144 making all RunL()s of short duration. |
|
145 |
|
146 3. The RunL() may be delayed because other, higher-priority, active objects are |
|
147 scheduled instead. This can be avoided by making CTimers very high-priority. |
|
148 |
|
149 @param anInterval Interval after which event is to occur, in microseconds. |
|
150 |
|
151 @panic USER 87, if anInterval is negative. This is raised by the |
|
152 underlying RTimer. |
|
153 @panic E32USER-CBase 51, if the active object has not been added to an |
|
154 active scheduler. |
|
155 |
|
156 @see RTimer |
|
157 */ |
|
158 { |
|
159 |
|
160 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
161 iTimer.After(iStatus,anInterval); |
|
162 SetActive(); |
|
163 } |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 EXPORT_C void CTimer::Lock(TTimerLockSpec aLock) |
|
169 /** |
|
170 Requests an event on a specified second fraction. |
|
171 |
|
172 Note that the RunL() function is run exactly on the specified second fraction. |
|
173 |
|
174 @param aLock The fraction of a second at which the timer completes. |
|
175 */ |
|
176 { |
|
177 |
|
178 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
179 iTimer.Lock(iStatus,aLock); |
|
180 SetActive(); |
|
181 } |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 EXPORT_C void CTimer::Inactivity(TTimeIntervalSeconds aSeconds) |
|
187 /** |
|
188 Requests an event if no activity occurs within the specified interval. |
|
189 |
|
190 @param aSeconds The time interval. |
|
191 */ |
|
192 { |
|
193 |
|
194 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
195 iTimer.Inactivity(iStatus, aSeconds); |
|
196 SetActive(); |
|
197 } |
|
198 |
|
199 |
|
200 |
|
201 EXPORT_C void CTimer::HighRes(TTimeIntervalMicroSeconds32 aInterval) |
|
202 /** |
|
203 Requests an event after the specified interval to a resolution of 1ms. |
|
204 The "HighRes timer" counter stops during power-down (the same as "after timer"). |
|
205 |
|
206 @param aInterval The time interval, in microseconds, after which an event |
|
207 is to occur. |
|
208 @panic USER 87, if anInterval is negative. This is raised by the |
|
209 underlying RTimer. |
|
210 @panic KERN-EXEC 15, if this function is called while a request for a timer |
|
211 event is still outstanding. |
|
212 */ |
|
213 { |
|
214 |
|
215 __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); |
|
216 iTimer.HighRes(iStatus, aInterval); |
|
217 SetActive(); |
|
218 } |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 EXPORT_C void CTimer::ConstructL() |
|
224 /** |
|
225 Constructs a new asynchronous timer. |
|
226 |
|
227 The function must be called before any timer requests (i.e. calls to |
|
228 RTimer::After() or RTimer::At()) can be made. |
|
229 |
|
230 Since it is protected, it cannot be called directly by clients of CTimer |
|
231 derived classes. Typically, a derived class makes a base call to this function |
|
232 in the second phase of two-phase construction; i.e. the derived class defines |
|
233 and implements its own ConstructL() function within which it makes a base |
|
234 call to CTimer::ConstructL(). |
|
235 */ |
|
236 { |
|
237 |
|
238 TInt r=iTimer.CreateLocal(); |
|
239 if (r!=KErrNone) |
|
240 User::Leave(r); |
|
241 } |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 EXPORT_C void CTimer::DoCancel() |
|
247 // |
|
248 // Cancel the timer. |
|
249 // |
|
250 { |
|
251 |
|
252 iTimer.Cancel(); |
|
253 } |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 EXPORT_C CPeriodic *CPeriodic::New(TInt aPriority) |
|
259 /** |
|
260 Allocates and constructs a CPeriodic object - non-leaving. |
|
261 |
|
262 Specify a high priority so the callback function is scheduled as soon as |
|
263 possible after the timer events complete. |
|
264 |
|
265 @param aPriority The priority of the active object. If timing is critical, |
|
266 it should be higher than that of all other active objects |
|
267 owned by the scheduler. |
|
268 |
|
269 @return Pointer to new CPeriodic object. The object is initialised and added |
|
270 to the active scheduler. This value is NULL if there is insufficient |
|
271 memory. |
|
272 */ |
|
273 { |
|
274 |
|
275 CPeriodic *pP=new CPeriodic(aPriority); |
|
276 if (pP) |
|
277 { |
|
278 TRAPD(r,pP->ConstructL()); |
|
279 if (r==KErrNone) |
|
280 CActiveScheduler::Add(pP); |
|
281 else |
|
282 { |
|
283 delete pP; |
|
284 pP=NULL; |
|
285 } |
|
286 } |
|
287 return pP; |
|
288 } |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 EXPORT_C CPeriodic *CPeriodic::NewL(TInt aPriority) |
|
294 /** |
|
295 Allocates and constructs a CPeriodic object - leaving. |
|
296 |
|
297 Specify a high priority so the callback function is scheduled as soon as |
|
298 possible after the timer events complete. |
|
299 |
|
300 @param aPriority The priority of the active object. If timing is critical, |
|
301 it should be higher than that of all other active objects |
|
302 owned by the scheduler. |
|
303 |
|
304 @return Pointer to new CPeriodic object. The object is initialised and added |
|
305 to the active scheduler. |
|
306 |
|
307 @leave KErrNoMemory There is insufficient memory to create the object. |
|
308 */ |
|
309 { |
|
310 |
|
311 return((CPeriodic *)User::LeaveIfNull(New(aPriority))); |
|
312 } |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 EXPORT_C CPeriodic::CPeriodic(TInt aPriority) |
|
318 : CTimer(aPriority) |
|
319 /** |
|
320 Protected constructor with priority. |
|
321 |
|
322 Use this constructor to set the priority of the active object. |
|
323 |
|
324 Classes derived from CPeriodic must define and provide a constructor through |
|
325 which the priority of the active object can be passed. Such a constructor |
|
326 can call CPeriodic's constructor in its constructor initialisation list. |
|
327 |
|
328 @param aPriority The priority of the timer. |
|
329 */ |
|
330 { |
|
331 } |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 EXPORT_C CPeriodic::~CPeriodic() |
|
337 /** |
|
338 Destructor. |
|
339 |
|
340 Frees resources prior to destruction. |
|
341 */ |
|
342 { |
|
343 } |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 EXPORT_C void CPeriodic::Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32 anInterval,TCallBack aCallBack) |
|
349 /** |
|
350 Starts generating periodic events. |
|
351 |
|
352 The event calls the protected RunL() function, |
|
353 which in turn calls the function specified by aCallBack. The first event is |
|
354 generated after aDelay microseconds; subsequent events are generated regularly |
|
355 thereafter at intervals of anInterval microseconds. |
|
356 |
|
357 The TCallBack contains a function pointer and a TAny* pointer. The function |
|
358 will be repeatedly called with the pointer as a parameter. |
|
359 |
|
360 Once started, periodic events are generated until the CPeriodic object is |
|
361 destroyed. |
|
362 |
|
363 Notes: |
|
364 |
|
365 1. The callback function will be run as soon as possible after the initial delay, |
|
366 and after each period. |
|
367 |
|
368 2. The callback may be delayed because the RunL() of another active object, with |
|
369 the deepest nesting-level active scheduler on the same thread, is running |
|
370 when the event occurs: this cannot be avoided, but can be minimised by making |
|
371 all RunL()s of short duration. |
|
372 |
|
373 3. The callback may be delayed because other, higher-priority, active objects |
|
374 are scheduled instead. This can be avoided by giving the CPeriodic a very |
|
375 high priority. |
|
376 |
|
377 @param aDelay The delay from the Start() function to the generation of the |
|
378 first event, in microseconds. |
|
379 @param anInterval The interval between events generated after the initial |
|
380 delay, in microseconds. |
|
381 @param aCallBack A callback specifying a function to be called when the CPeriodic |
|
382 is scheduled after a timer event. |
|
383 |
|
384 @panic E32USER-CBase 52, if anInterval is negative. |
|
385 @panic E32USER-CBase 53, if aDelay is negative. |
|
386 */ |
|
387 { |
|
388 |
|
389 __ASSERT_ALWAYS(anInterval.Int()>=0,Panic(ETimIntervalNegativeOrZero)); |
|
390 __ASSERT_ALWAYS(aDelay.Int()>=0,Panic(ETimDelayNegative)); |
|
391 iInterval=anInterval.Int(); |
|
392 iCallBack=aCallBack; |
|
393 After(aDelay); |
|
394 } |
|
395 |
|
396 EXPORT_C void CPeriodic::RunL() |
|
397 // |
|
398 // Handle completion by issuing the next request and then calling back. |
|
399 // |
|
400 { |
|
401 |
|
402 After(iInterval); |
|
403 iCallBack.CallBack(); |
|
404 } |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 EXPORT_C CHeartbeat::CHeartbeat(TInt aPriority) |
|
410 : CTimer(aPriority) |
|
411 /** |
|
412 Protected constructor with a priority. Use this constructor to set the priority |
|
413 of the active object. |
|
414 |
|
415 Classes derived from CHeartbeat must define and provide a constructor through |
|
416 which the priority of the active object can be passed. Such a constructor |
|
417 can call CHeartbeat's constructor in its constructor initialisation list. |
|
418 |
|
419 @param aPriority The priority of the timer. |
|
420 */ |
|
421 {} |
|
422 |
|
423 |
|
424 |
|
425 |
|
426 EXPORT_C CHeartbeat *CHeartbeat::New(TInt aPriority) |
|
427 /** |
|
428 Allocates and constructs a CHeartbeat object - non-leaving. |
|
429 |
|
430 Specify a high priority so the callback function is scheduled as soon as |
|
431 possible after the timer events complete. |
|
432 |
|
433 @param aPriority The priority of the active object. If timing is critical, |
|
434 it should be higher than that of all other active objects |
|
435 owned by the scheduler. |
|
436 |
|
437 @return Pointer to new CHeartbeat object. The object is initialised and added |
|
438 to the active scheduler. This value is NULL if insufficient memory was |
|
439 available. |
|
440 */ |
|
441 { |
|
442 |
|
443 CHeartbeat *pP=new CHeartbeat(aPriority); |
|
444 if (pP) |
|
445 { |
|
446 TRAPD(r,pP->ConstructL()); |
|
447 if (r==KErrNone) |
|
448 CActiveScheduler::Add(pP); |
|
449 else |
|
450 { |
|
451 delete pP; |
|
452 pP=NULL; |
|
453 } |
|
454 } |
|
455 return pP; |
|
456 } |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 EXPORT_C CHeartbeat *CHeartbeat::NewL(TInt aPriority) |
|
462 /** |
|
463 Allocates and constructs a CHeartbeat object - leaving. |
|
464 |
|
465 Specify a high priority so the callback function is scheduled as soon as |
|
466 possible after the timer events complete. |
|
467 |
|
468 @param aPriority The priority of the active object. If timing is critical, |
|
469 it should be higher than that of all other active objects |
|
470 owned by the scheduler. |
|
471 |
|
472 @return Pointer to new CHeartbeat object. The object is initialised and added |
|
473 to the active scheduler. |
|
474 */ |
|
475 { |
|
476 |
|
477 return((CHeartbeat *)User::LeaveIfNull(New(aPriority))); |
|
478 } |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 EXPORT_C CHeartbeat::~CHeartbeat() |
|
484 /** |
|
485 Destructor. |
|
486 |
|
487 Frees resources prior to destruction. |
|
488 */ |
|
489 {} |
|
490 |
|
491 |
|
492 |
|
493 |
|
494 EXPORT_C void CHeartbeat::Start(TTimerLockSpec aLock, MBeating *aBeating) |
|
495 /** |
|
496 Starts generating heartbeat events. The event results in calls to the Beat() |
|
497 and Synchronize() functions specified by aBeating. |
|
498 |
|
499 The first event is generated on the first fraction of a second corresponding |
|
500 to aLock that occurs after Start() has returned; subsequent events are generated |
|
501 regularly thereafter at one second intervals on the second fraction specified |
|
502 by aLock. |
|
503 |
|
504 The aBeating mixin must be written by the user. Most of the time, its Beat() |
|
505 function is called which trivially updates the tick count. Occasionally, synchronisation |
|
506 is lost, and the Synchronize() function is called instead: this must find |
|
507 out from the system time how many ticks should have been counted, and update |
|
508 things accordingly. |
|
509 |
|
510 Once started, heartbeat events are generated until the CHeartbeat object is |
|
511 destroyed. |
|
512 |
|
513 @param aLock The fraction of a second at which the timer completes. |
|
514 @param aBeating Provides the Beat() and Synchronize() functions. |
|
515 */ |
|
516 { |
|
517 |
|
518 iBeating=aBeating; |
|
519 iLock=aLock; |
|
520 Lock(aLock); |
|
521 } |
|
522 |
|
523 |
|
524 |
|
525 |
|
526 EXPORT_C void CHeartbeat::RunL() |
|
527 // |
|
528 // Handle completion |
|
529 // |
|
530 { |
|
531 |
|
532 TRequestStatus stat=iStatus; |
|
533 Lock(iLock); |
|
534 if (stat==KErrNone) |
|
535 iBeating->Beat(); |
|
536 else |
|
537 iBeating->Synchronize(); |
|
538 } |
|
539 |