First public contribution.
1 // Copyright (c) 1996-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\cbase\ub_dtim.cpp
21 Creates a new timed event queue with the specified active object priority.
23 @param aPriority The priority of this active object.
25 @return On successful return, a pointer to the queue of timed events.
30 EXPORT_C CDeltaTimer* CDeltaTimer::NewL(TInt aPriority)
32 TTimeIntervalMicroSeconds32 tickPeriod;
33 UserHal::TickPeriod(tickPeriod);
35 CDeltaTimer* timer = new(ELeave) CDeltaTimer(aPriority, tickPeriod.Int());
37 TInt err = timer->iTimer.CreateLocal();
45 CActiveScheduler::Add(timer);
51 Creates a new timed event queue with the specified active object priority, and
52 the specified timer granularity.
54 @param aPriority The priority of this active object.
55 @param aGranularity Ignored. The resolution of the timer is the tick period.
57 @return On successful return, a pointer to the queue of timed events.
62 EXPORT_C CDeltaTimer* CDeltaTimer::NewL(TInt aPriority, TTimeIntervalMicroSeconds32 /*aGranularity*/)
64 return CDeltaTimer::NewL(aPriority);
68 Constructor taking an active object priority value.
70 The constructor sets this active object's priority value through a call to
71 the base class constructor in its c'tor list.
73 @param aPriority The priority of this active object.
74 @param aTickPeriod The period of a tick on the system.
79 CDeltaTimer::CDeltaTimer(TInt aPriority, TInt aTickPeriod)
80 : CActive(aPriority), iTickPeriod(aTickPeriod)
85 Adds a new timed event entry into the timed event queue.
87 @param aTimeInMicroSeconds The interval from the present time when the timed
88 event entry is to expire.
89 @param aEntry The timed event entry encapsulating the call back that
90 is to be called when this timed event entry expires.
95 EXPORT_C void CDeltaTimer::Queue(TTimeIntervalMicroSeconds32 aTimeInMicroSeconds, TDeltaTimerEntry& aEntry)
97 QueueLong(TTimeIntervalMicroSeconds(MAKE_TINT64(0, aTimeInMicroSeconds.Int())), aEntry);
101 Adds a new timed event entry into the timed event queue.
103 @param aTimeInMicroSeconds The interval from the present time when the timed
104 event entry is to expire.
105 @param aEntry The timed event entry encapsulating the call back that
106 is to be called when this timed event entry expires.
108 @return KErrNone if sucessful, KErrOverflow if the interval is too great or negative.
113 EXPORT_C TInt CDeltaTimer::QueueLong(TTimeIntervalMicroSeconds aTimeInMicroSeconds, TDeltaTimerEntry& aEntry)
115 const TInt64 timeInTicks = (aTimeInMicroSeconds.Int64() + iTickPeriod - 1) / iTickPeriod;
117 TInt timeInTicks32 = I64LOW(timeInTicks);
119 // We are using deltas on tick values, hence using maximum signed number of ticks
120 if (I64HIGH(timeInTicks) || (timeInTicks32 < 0))
125 // Make sure we queue for at least one tick
126 if (timeInTicks32 == 0)
131 // Calculate tick count for new entry
132 aEntry.iLink.iTickCount = Exec::TickCount() + timeInTicks32;
134 // Add this entry at the right spot
135 iQueue.Add(aEntry.iLink);
137 // Queue the timer, re-queuing if we've added to the head of the queue
138 Activate(&aEntry.iLink == iQueue.First());
144 Issues a new RTimer request, if there is no outstanding request and the queue
150 void CDeltaTimer::Activate(TBool aRequeueTimer)
152 // Queue a request on the timer.
167 if (!iQueue.IsEmpty() && !iQueueBusy)
171 const TInt ticksToWait = iQueue.First()->iTickCount - Exec::TickCount();
175 iTimer.AfterTicks(iStatus, ticksToWait);
179 TRequestStatus* status = &iStatus;
180 User::RequestComplete(status, KErrNone);
186 Deals with an RTimer completion event.
188 The function inspects the timed event entry at the head of the queue, and
189 reduces its timer value by the appropriate amount. If this timed event is
190 now found to have expired, the call back function is called, and the timed
191 event entry removed from the queue.
193 If the timed event entry has not expired, it remains at the head of the queue.
195 The function issues a new RTimer request, using the timer granularity value
196 as the time interval.
204 void CDeltaTimer::RunL()
206 // Call all zero delta callbacks
211 // Whilst the list of expired timers is being processed, time will pass and
212 // the tick count may have increased such that there are now more expired
213 // timers. Loop until we have either emptied the queue or can wait for a
214 // timer exipration in the future.
215 while (!iQueue.IsEmpty())
217 // Calculate how long till first timer expires
218 const TUint tickCount = Exec::TickCount();
220 // If the first timer is yet to expire, wait some more
221 if (((TInt)(iQueue.First()->iTickCount - tickCount)) > 0)
226 // Remove entry before callback to prevent re-entrancy issues
227 TTickCountQueLink* entry = iQueue.RemoveFirst();
229 // Iterate through the timers we know have expired based on the
230 // last calculation of delta
233 // Make callback. This could go reentrant on Queue[Long]() or Remove().
234 reinterpret_cast<TDeltaTimerEntry*>(
237 _FOFF(TDeltaTimerEntry, iLink)
239 ->iCallBack.CallBack();
241 // Remove the next expired entry, if any
242 entry = iQueue.RemoveFirst(tickCount);
254 Implements cancellation of an oustanding RTimer request.
259 void CDeltaTimer::DoCancel()
265 Removes the specified timed event entry from the timer queue.
267 @param aEntry The timed event entry.
272 EXPORT_C void CDeltaTimer::Remove(TDeltaTimerEntry& aEntry)
274 // Remove the specified entry from the list
275 aEntry.iLink.Deque();
281 Frees all resources before destruction of the object. Specifically, it cancels
282 any outstanding timer requests generated by the RTimer object and then deletes
283 all timed event entries from the timed event queue.
290 CDeltaTimer::~CDeltaTimer()
294 while (!iQueue.IsEmpty())
296 iQueue.First()->Deque();