sl@0: // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\euser\cbase\ub_tim.cpp sl@0: // sl@0: // sl@0: sl@0: #include "ub_std.h" sl@0: sl@0: EXPORT_C CTimer::CTimer(TInt aPriority) sl@0: : CActive(aPriority) sl@0: /** sl@0: Protected constructor with priority. sl@0: sl@0: Use this constructor to set the priority of the active object. sl@0: sl@0: Classes derived from CTimer must define and provide a constructor through sl@0: which the priority of the active object can be passed. Such a constructor sl@0: can call CTimer's constructor in its constructor initialisation list. sl@0: sl@0: @param aPriority The priority of the timer. sl@0: */ sl@0: { sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CTimer::~CTimer() sl@0: /** sl@0: Destructor. sl@0: sl@0: Frees resources prior to destruction. Specifically, it cancels any outstanding sl@0: request and closes the RTimer handle. sl@0: */ sl@0: { sl@0: sl@0: Cancel(); sl@0: iTimer.Close(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::At(const TTime &aTime) sl@0: /** sl@0: Requests an event at a given local time. sl@0: sl@0: This timer completes at the specified time - if the machine is in a sl@0: turned off state at that time, the machine will be turned on again. sl@0: sl@0: Notes: sl@0: sl@0: 1. The CTimer' RunL() function will be run as soon as possible after the sl@0: specified system time. sl@0: sl@0: 2. The RunL() may be delayed because the RunL() of another active object, with sl@0: the deepest nesting-level active scheduler on the same thread, is running sl@0: when the event occurs: this cannot be avoided, but can be minimised by sl@0: making all RunL()s of short duration. sl@0: sl@0: 3. The RunL() may be delayed because other, higher-priority, active objects are sl@0: scheduled instead. This can be avoided by making CTimers very high-priority. sl@0: sl@0: 4. The TTime object should be set to the home time. sl@0: sl@0: @param aTime The local time at which the event is to occur. sl@0: sl@0: @see TTime::HomeTime sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.At(iStatus,aTime); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::AtUTC(const TTime &aTimeInUTC) sl@0: /** sl@0: Requests an event at a given UTC time. sl@0: sl@0: This timer completes at the specified time - if the machine is in a sl@0: turned off state at that time, the machine will be turned on again. sl@0: sl@0: Notes: sl@0: sl@0: 1. The CTimer' RunL() function will be run as soon as possible after the sl@0: specified system time. sl@0: sl@0: 2. The RunL() may be delayed because the RunL() of another active object, with sl@0: the deepest nesting-level active scheduler on the same thread, is running sl@0: when the event occurs: this cannot be avoided, but can be minimised by sl@0: making all RunL()s of short duration. sl@0: sl@0: 3. The RunL() may be delayed because other, higher-priority, active objects are sl@0: scheduled instead. This can be avoided by making CTimers very high-priority. sl@0: sl@0: 4. The TTime object should be set to the universal time. sl@0: sl@0: @param aTime The UTC time at which the event is to occur. sl@0: sl@0: @see TTime::UniversalTime sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.AtUTC(iStatus,aTimeInUTC); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::After(TTimeIntervalMicroSeconds32 anInterval) sl@0: /** sl@0: Requests an event after an interval. sl@0: sl@0: This timer completes after the specified number of microseconds. The sl@0: "after timer" counter stops during power-down. Therefore, a 5-second timer sl@0: will complete late if the machine is turned off 2 seconds after the request sl@0: is made. sl@0: sl@0: Notes: sl@0: sl@0: 1. The CTimer's RunL() function will be run as soon as possible after the sl@0: specified interval. sl@0: sl@0: 2. The RunL() may be delayed because the RunL() of another active object, with sl@0: the deepest nesting-level active scheduler on the same thread, is running sl@0: when the event occurs: this cannot be avoided, but can be minimised by sl@0: making all RunL()s of short duration. sl@0: sl@0: 3. The RunL() may be delayed because other, higher-priority, active objects are sl@0: scheduled instead. This can be avoided by making CTimers very high-priority. sl@0: sl@0: @param anInterval Interval after which event is to occur, in microseconds. sl@0: sl@0: @panic USER 87, if anInterval is negative. This is raised by the sl@0: underlying RTimer. sl@0: @panic E32USER-CBase 51, if the active object has not been added to an sl@0: active scheduler. sl@0: sl@0: @see RTimer sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.After(iStatus,anInterval); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::Lock(TTimerLockSpec aLock) sl@0: /** sl@0: Requests an event on a specified second fraction. sl@0: sl@0: Note that the RunL() function is run exactly on the specified second fraction. sl@0: sl@0: @param aLock The fraction of a second at which the timer completes. sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.Lock(iStatus,aLock); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::Inactivity(TTimeIntervalSeconds aSeconds) sl@0: /** sl@0: Requests an event if no activity occurs within the specified interval. sl@0: sl@0: @param aSeconds The time interval. sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.Inactivity(iStatus, aSeconds); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::HighRes(TTimeIntervalMicroSeconds32 aInterval) sl@0: /** sl@0: Requests an event after the specified interval to a resolution of 1ms. sl@0: The "HighRes timer" counter stops during power-down (the same as "after timer"). sl@0: sl@0: @param aInterval The time interval, in microseconds, after which an event sl@0: is to occur. sl@0: @panic USER 87, if anInterval is negative. This is raised by the sl@0: underlying RTimer. sl@0: @panic KERN-EXEC 15, if this function is called while a request for a timer sl@0: event is still outstanding. sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded)); sl@0: iTimer.HighRes(iStatus, aInterval); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::ConstructL() sl@0: /** sl@0: Constructs a new asynchronous timer. sl@0: sl@0: The function must be called before any timer requests (i.e. calls to sl@0: RTimer::After() or RTimer::At()) can be made. sl@0: sl@0: Since it is protected, it cannot be called directly by clients of CTimer sl@0: derived classes. Typically, a derived class makes a base call to this function sl@0: in the second phase of two-phase construction; i.e. the derived class defines sl@0: and implements its own ConstructL() function within which it makes a base sl@0: call to CTimer::ConstructL(). sl@0: */ sl@0: { sl@0: sl@0: TInt r=iTimer.CreateLocal(); sl@0: if (r!=KErrNone) sl@0: User::Leave(r); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CTimer::DoCancel() sl@0: // sl@0: // Cancel the timer. sl@0: // sl@0: { sl@0: sl@0: iTimer.Cancel(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CPeriodic *CPeriodic::New(TInt aPriority) sl@0: /** sl@0: Allocates and constructs a CPeriodic object - non-leaving. sl@0: sl@0: Specify a high priority so the callback function is scheduled as soon as sl@0: possible after the timer events complete. sl@0: sl@0: @param aPriority The priority of the active object. If timing is critical, sl@0: it should be higher than that of all other active objects sl@0: owned by the scheduler. sl@0: sl@0: @return Pointer to new CPeriodic object. The object is initialised and added sl@0: to the active scheduler. This value is NULL if there is insufficient sl@0: memory. sl@0: */ sl@0: { sl@0: sl@0: CPeriodic *pP=new CPeriodic(aPriority); sl@0: if (pP) sl@0: { sl@0: TRAPD(r,pP->ConstructL()); sl@0: if (r==KErrNone) sl@0: CActiveScheduler::Add(pP); sl@0: else sl@0: { sl@0: delete pP; sl@0: pP=NULL; sl@0: } sl@0: } sl@0: return pP; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CPeriodic *CPeriodic::NewL(TInt aPriority) sl@0: /** sl@0: Allocates and constructs a CPeriodic object - leaving. sl@0: sl@0: Specify a high priority so the callback function is scheduled as soon as sl@0: possible after the timer events complete. sl@0: sl@0: @param aPriority The priority of the active object. If timing is critical, sl@0: it should be higher than that of all other active objects sl@0: owned by the scheduler. sl@0: sl@0: @return Pointer to new CPeriodic object. The object is initialised and added sl@0: to the active scheduler. sl@0: sl@0: @leave KErrNoMemory There is insufficient memory to create the object. sl@0: */ sl@0: { sl@0: sl@0: return((CPeriodic *)User::LeaveIfNull(New(aPriority))); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CPeriodic::CPeriodic(TInt aPriority) sl@0: : CTimer(aPriority) sl@0: /** sl@0: Protected constructor with priority. sl@0: sl@0: Use this constructor to set the priority of the active object. sl@0: sl@0: Classes derived from CPeriodic must define and provide a constructor through sl@0: which the priority of the active object can be passed. Such a constructor sl@0: can call CPeriodic's constructor in its constructor initialisation list. sl@0: sl@0: @param aPriority The priority of the timer. sl@0: */ sl@0: { sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CPeriodic::~CPeriodic() sl@0: /** sl@0: Destructor. sl@0: sl@0: Frees resources prior to destruction. sl@0: */ sl@0: { sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CPeriodic::Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32 anInterval,TCallBack aCallBack) sl@0: /** sl@0: Starts generating periodic events. sl@0: sl@0: The event calls the protected RunL() function, sl@0: which in turn calls the function specified by aCallBack. The first event is sl@0: generated after aDelay microseconds; subsequent events are generated regularly sl@0: thereafter at intervals of anInterval microseconds. sl@0: sl@0: The TCallBack contains a function pointer and a TAny* pointer. The function sl@0: will be repeatedly called with the pointer as a parameter. sl@0: sl@0: Once started, periodic events are generated until the CPeriodic object is sl@0: destroyed. sl@0: sl@0: Notes: sl@0: sl@0: 1. The callback function will be run as soon as possible after the initial delay, sl@0: and after each period. sl@0: sl@0: 2. The callback may be delayed because the RunL() of another active object, with sl@0: the deepest nesting-level active scheduler on the same thread, is running sl@0: when the event occurs: this cannot be avoided, but can be minimised by making sl@0: all RunL()s of short duration. sl@0: sl@0: 3. The callback may be delayed because other, higher-priority, active objects sl@0: are scheduled instead. This can be avoided by giving the CPeriodic a very sl@0: high priority. sl@0: sl@0: @param aDelay The delay from the Start() function to the generation of the sl@0: first event, in microseconds. sl@0: @param anInterval The interval between events generated after the initial sl@0: delay, in microseconds. sl@0: @param aCallBack A callback specifying a function to be called when the CPeriodic sl@0: is scheduled after a timer event. sl@0: sl@0: @panic E32USER-CBase 52, if anInterval is negative. sl@0: @panic E32USER-CBase 53, if aDelay is negative. sl@0: */ sl@0: { sl@0: sl@0: __ASSERT_ALWAYS(anInterval.Int()>=0,Panic(ETimIntervalNegativeOrZero)); sl@0: __ASSERT_ALWAYS(aDelay.Int()>=0,Panic(ETimDelayNegative)); sl@0: iInterval=anInterval.Int(); sl@0: iCallBack=aCallBack; sl@0: After(aDelay); sl@0: } sl@0: sl@0: EXPORT_C void CPeriodic::RunL() sl@0: // sl@0: // Handle completion by issuing the next request and then calling back. sl@0: // sl@0: { sl@0: sl@0: After(iInterval); sl@0: iCallBack.CallBack(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CHeartbeat::CHeartbeat(TInt aPriority) sl@0: : CTimer(aPriority) sl@0: /** sl@0: Protected constructor with a priority. Use this constructor to set the priority sl@0: of the active object. sl@0: sl@0: Classes derived from CHeartbeat must define and provide a constructor through sl@0: which the priority of the active object can be passed. Such a constructor sl@0: can call CHeartbeat's constructor in its constructor initialisation list. sl@0: sl@0: @param aPriority The priority of the timer. sl@0: */ sl@0: {} sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CHeartbeat *CHeartbeat::New(TInt aPriority) sl@0: /** sl@0: Allocates and constructs a CHeartbeat object - non-leaving. sl@0: sl@0: Specify a high priority so the callback function is scheduled as soon as sl@0: possible after the timer events complete. sl@0: sl@0: @param aPriority The priority of the active object. If timing is critical, sl@0: it should be higher than that of all other active objects sl@0: owned by the scheduler. sl@0: sl@0: @return Pointer to new CHeartbeat object. The object is initialised and added sl@0: to the active scheduler. This value is NULL if insufficient memory was sl@0: available. sl@0: */ sl@0: { sl@0: sl@0: CHeartbeat *pP=new CHeartbeat(aPriority); sl@0: if (pP) sl@0: { sl@0: TRAPD(r,pP->ConstructL()); sl@0: if (r==KErrNone) sl@0: CActiveScheduler::Add(pP); sl@0: else sl@0: { sl@0: delete pP; sl@0: pP=NULL; sl@0: } sl@0: } sl@0: return pP; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CHeartbeat *CHeartbeat::NewL(TInt aPriority) sl@0: /** sl@0: Allocates and constructs a CHeartbeat object - leaving. sl@0: sl@0: Specify a high priority so the callback function is scheduled as soon as sl@0: possible after the timer events complete. sl@0: sl@0: @param aPriority The priority of the active object. If timing is critical, sl@0: it should be higher than that of all other active objects sl@0: owned by the scheduler. sl@0: sl@0: @return Pointer to new CHeartbeat object. The object is initialised and added sl@0: to the active scheduler. sl@0: */ sl@0: { sl@0: sl@0: return((CHeartbeat *)User::LeaveIfNull(New(aPriority))); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C CHeartbeat::~CHeartbeat() sl@0: /** sl@0: Destructor. sl@0: sl@0: Frees resources prior to destruction. sl@0: */ sl@0: {} sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CHeartbeat::Start(TTimerLockSpec aLock, MBeating *aBeating) sl@0: /** sl@0: Starts generating heartbeat events. The event results in calls to the Beat() sl@0: and Synchronize() functions specified by aBeating. sl@0: sl@0: The first event is generated on the first fraction of a second corresponding sl@0: to aLock that occurs after Start() has returned; subsequent events are generated sl@0: regularly thereafter at one second intervals on the second fraction specified sl@0: by aLock. sl@0: sl@0: The aBeating mixin must be written by the user. Most of the time, its Beat() sl@0: function is called which trivially updates the tick count. Occasionally, synchronisation sl@0: is lost, and the Synchronize() function is called instead: this must find sl@0: out from the system time how many ticks should have been counted, and update sl@0: things accordingly. sl@0: sl@0: Once started, heartbeat events are generated until the CHeartbeat object is sl@0: destroyed. sl@0: sl@0: @param aLock The fraction of a second at which the timer completes. sl@0: @param aBeating Provides the Beat() and Synchronize() functions. sl@0: */ sl@0: { sl@0: sl@0: iBeating=aBeating; sl@0: iLock=aLock; sl@0: Lock(aLock); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void CHeartbeat::RunL() sl@0: // sl@0: // Handle completion sl@0: // sl@0: { sl@0: sl@0: TRequestStatus stat=iStatus; sl@0: Lock(iLock); sl@0: if (stat==KErrNone) sl@0: iBeating->Beat(); sl@0: else sl@0: iBeating->Synchronize(); sl@0: } sl@0: