kernel/eka/euser/cbase/ub_tim.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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