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