systemhealthmanagement/systemhealthmgr/sysmonsrc/monitor.cpp
changeset 0 4e1aa6a622a0
child 21 ccb4f6b3db21
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2006-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 "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 //
       
    15 
       
    16 #include <e32svr.h>
       
    17 #include "monitor.h"
       
    18 #include "startsafe.h"
       
    19 #include "restartsys.h"
       
    20 #include "sysmonserver.h"
       
    21 #include "sysmoncliserv.h"
       
    22 #include "timerlist.h"
       
    23 #include "sysmon_patch.h"
       
    24 #include <startupproperties.h>
       
    25 
       
    26 #include "shmadebug.h"
       
    27 #include "shmapanic.h"
       
    28 #include <u32hal.h>
       
    29 
       
    30 const TInt CMonitor::iOffset = _FOFF(CMonitor, iSglQueLink);
       
    31 const TInt KDelayRequiredForRestartSys = 5000000;	 // required by RestartSys API, see comments in RestartSys::RestartSystem()
       
    32 
       
    33 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
    34 _LIT(KRestartSysProxyDLL, "restartsys.dll");
       
    35 _LIT(KCustomisedRestartSysProxyDLL, "custrestartsys.dll");
       
    36 typedef TInt (*TFuncRestartL)(void);
       
    37 typedef TInt (*TFuncRestartWithModeL)(TInt);
       
    38 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
    39 
       
    40 TProcessId CMonitor::ProcessId() const
       
    41 	{
       
    42 	return iProcessId;
       
    43 	}	
       
    44 
       
    45 
       
    46 CMonitor* CMonitor::NewL(CSysMonServer& aServer, const TProcessId& aId, CStartupProperties* aStartupProperties, TBool aExecuteRecoveryMethodOnFailure)
       
    47 	{
       
    48 	ASSERT(aStartupProperties);
       
    49 	CMonitor *monitor = new(ELeave) CMonitor(aServer, aId);
       
    50 	CleanupStack::PushL(monitor);
       
    51 	monitor->ConstructL(aStartupProperties, aExecuteRecoveryMethodOnFailure);
       
    52 	CleanupStack::Pop(monitor);
       
    53 	return monitor;
       
    54 	}
       
    55 
       
    56 
       
    57 CMonitor::CMonitor(CSysMonServer& aServer, const TProcessId& aId)
       
    58 	:CActive(EPriorityHigh),
       
    59 	iSysMonServer(aServer),
       
    60 	iProcessId(aId),
       
    61 	iProcess(aId),
       
    62 	iLoadTime()
       
    63 	{
       
    64 	CActiveScheduler::Add(this);
       
    65 	}
       
    66 
       
    67 
       
    68 void CMonitor::ConstructL(CStartupProperties* aStartupProperties, TBool aExecuteRecoveryMethodOnFailure)
       
    69 	{
       
    70 	iLogonBackoffTimer = CLogonBackoffTimer::NewL( *this );
       
    71 	
       
    72 	User::LeaveIfError(iProcess.Open(iProcessId));
       
    73 	
       
    74 	// Don't support monitoring of system critical components as they will restart the device on failure anyway
       
    75 	User::TCritical critical = User::ProcessCritical(iProcess);
       
    76 	if (critical == User::ESystemCritical || critical == User::ESystemPermanent)
       
    77 		{
       
    78 		User::Leave(KErrNotSupported);
       
    79 		}
       
    80 	
       
    81 	//Make sure the process is still running
       
    82 	if((EExitPending == iProcess.ExitType()))
       
    83 		{
       
    84 		//Ensure the the filename in aStartupProperties is the same as in iProcess
       
    85 		//(not possible to read filename from a dead process).
       
    86 		TParse nameInProc, nameInProp;
       
    87 		nameInProc.SetNoWild(iProcess.FileName(),NULL,NULL);
       
    88 		nameInProp.SetNoWild(aStartupProperties->FileName(),NULL,NULL);
       
    89 		
       
    90 		if( nameInProc.Name().CompareF(nameInProp.Name()) )
       
    91 			{
       
    92 			User::Leave(KErrArgument);
       
    93 			}
       
    94 		}
       
    95 	else
       
    96 		{
       
    97 		//The process is already dead, either leave now or let this monitor recover the process
       
    98 		if(!aExecuteRecoveryMethodOnFailure)
       
    99 			User::Leave(KErrDied);
       
   100 		}	
       
   101 	
       
   102 	iReLaunchAttempts = 0;	// No. of re-launch attempts at the start of monitering would be zero.
       
   103 	iReLaunchIntervalTimer = CRelaunchIntervalTimer::NewL(*this);
       
   104 
       
   105 	// Can't leave after taking ownership of aStartupProperties 
       
   106 	iStartupProperties = aStartupProperties;
       
   107 	iLoadTime.UniversalTime();		
       
   108 	}
       
   109 
       
   110 
       
   111 CMonitor::~CMonitor()
       
   112 	{
       
   113 	delete iReLaunchIntervalTimer;
       
   114 	delete iLogonBackoffTimer;
       
   115 	
       
   116 	Cancel();
       
   117 	delete iStartupProperties;
       
   118 	iProcess.Close();
       
   119 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   120 	iRestartSysLib.Close();
       
   121 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   122 	}
       
   123 
       
   124 
       
   125 void CMonitor::Start()
       
   126 	{
       
   127 	iLogonBackoffTimer->ProcessLogon();
       
   128 	}
       
   129 
       
   130 
       
   131 
       
   132 void CMonitor::DoCancel()
       
   133 	{
       
   134 #ifdef _DEBUG
       
   135 	TPtrC fileName = iStartupProperties->FileName();
       
   136 	DEBUGPRINT2(_L("SysMonMonitor: Monitor Cancelled for %S"), &(fileName));
       
   137 #endif
       
   138 
       
   139 	iProcess.LogonCancel(iStatus); // cancels monitoring
       
   140 	}
       
   141 
       
   142 
       
   143 void CMonitor::RestartProcessL()
       
   144 	{
       
   145 #ifdef _DEBUG
       
   146 	TPtrC fileName = iStartupProperties->FileName();
       
   147 #endif
       
   148 	DEBUGPRINT3(_L("SysMonMonitor: Going to restart %S, old process id=%u"), &fileName, iProcessId.Id());
       
   149 	
       
   150 	CStartSafe* startSafe = CStartSafe::NewL();	
       
   151 	CleanupStack::PushL(startSafe);
       
   152 	
       
   153 	// As the retries are now counted(after PREQ1871) over a period of time it does make sense for fire and forget processes to have a non-zero retries count.
       
   154 	__ASSERT_DEBUG((iStartupProperties->StartMethod() == EWaitForStart || iStartupProperties->StartMethod() == EFireAndForget), PanicNow(KPanicMonitor, EInvalidStartMethod));
       
   155 	
       
   156 	TInt propRetries = iStartupProperties->NoOfRetries();
       
   157 	TBool restoreRetries = EFalse;
       
   158 	
       
   159 	if(propRetries > 0)
       
   160 		{
       
   161 		// In the restart scenario we want StartSafe to make 'NoOfRetries' attempts
       
   162 		// rather than '1 + NoOfRetries' which it will otherwise do.
       
   163 		restoreRetries = ETrue;
       
   164 		iStartupProperties->SetNoOfRetries(--propRetries);	
       
   165 		}
       
   166 	
       
   167 	TInt retried = 0;
       
   168 	
       
   169 	// Attempt restart/s. Do not allow a leave until NoOfRetries has been restored.
       
   170 	TRAPD( err, startSafe->StartL(*iStartupProperties, iProcess, retried) );
       
   171 	
       
   172 	if(restoreRetries)
       
   173 		{
       
   174 		iStartupProperties->SetNoOfRetries(++propRetries);	
       
   175 		}
       
   176 		
       
   177 	User::LeaveIfError(err);
       
   178 	CleanupStack::PopAndDestroy(startSafe);	
       
   179 	DEBUGPRINT3(_L("SysMonMonitor: %S restarted, new iProcessId=%u. Logon to monitor again"), &fileName, iProcess.Id().Id());
       
   180 	
       
   181 	iProcessId = iProcess.Id();
       
   182 	iReLaunchAttempts++;	// Increment after each re-launch attempt.
       
   183 	if (!iReLaunchIntervalTimer->IsActive())
       
   184 		{
       
   185 		DEBUGPRINT3(_L("SysMonMonitor: ReLaunch Interval Timer is started for %S with processId %u"), &fileName, iProcessId.Id());
       
   186 		iReLaunchIntervalTimer->Start();
       
   187 		}
       
   188 	DEBUGPRINT3(_L("SysMonMonitor: ReLaunch Attempts for %S is %d"), &fileName, iReLaunchAttempts);
       
   189 	iLogonBackoffTimer->ProcessLogon();
       
   190 	}
       
   191 
       
   192 
       
   193 /**
       
   194  This function is inherited from MLogonCallback and is called from CLogonBackoffTimer
       
   195 */
       
   196 TInt CMonitor::DoProcessLogon()
       
   197 	{
       
   198 
       
   199 	iProcess.Logon( iStatus );
       
   200 	return ( (iStatus == KRequestPending) ? KErrNone : iStatus.Int() );
       
   201 	}
       
   202 
       
   203 
       
   204 
       
   205 /**
       
   206  This function is inherited from MLogonCallback and is called from CLogonBackoffTimer
       
   207 */
       
   208 void CMonitor::ActivateSelf()
       
   209 	{
       
   210 	
       
   211 	iLoadTime.UniversalTime();
       
   212 	SetActive();		
       
   213 	}
       
   214 	
       
   215 TInt CMonitor::Callback(TAny* aParent)
       
   216 	{		
       
   217 	CMonitor* monitor = reinterpret_cast<CMonitor*> (aParent);
       
   218 	DEBUGPRINT2(_L("SysMonMonitor: Finished waiting for throttle time, try to restart failed processId=%u"), monitor->iProcessId.Id());
       
   219 
       
   220  	 if (!monitor->HasExceededRateOfFailurePolicy())
       
   221 		{
       
   222 		TRAPD(err, monitor->RestartProcessL());
       
   223 		if (err != KErrNone)
       
   224 			{
       
   225 			// process failed to be started, cancel monitoring of this process
       
   226 			DEBUGPRINT2(_L("SysMonMonitor::RestartProcessL failed with err=%d, cancelling"), err);
       
   227 			monitor->CancelMonitor();
       
   228 			}
       
   229 		}
       
   230 	return KErrNone;
       
   231 	}
       
   232 	
       
   233 	
       
   234 /*
       
   235 CMonitor::RunL() gets called when a monitor process terminates.
       
   236 @panic ERestartSystemCallFailed if the RestartSystem call fails
       
   237 @panic ERestartSystemCallWithMode if the RestartSystem_with_mode call fails
       
   238 @panic EInvalidStartMethod if the Start mode is invalid
       
   239 */
       
   240 void CMonitor::RunL()
       
   241 	{
       
   242 	DEBUGPRINT1(_L("SysMonMonitor: CMonitor::RunL() called"));
       
   243 	
       
   244 	iProcess.Close();	// closing the current handle
       
   245 	
       
   246 	TRecoveryMethod recoveryMethod = iStartupProperties->RecoveryMethod();
       
   247 	if (recoveryMethod == ECriticalNoRetries)
       
   248 		{
       
   249 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   250 		// If the retry_failure_recovery_method is set to ECriticalNoRetries, then SysMon will restart
       
   251 		// the OS. It will not try to restart the process even if iStartupProperties->NoOfRetries() 
       
   252 		// is greater than zero.
       
   253 		RestartSysDll(EFalse);
       
   254 #else
       
   255 		TInt err = RestartSys::RestartSystem() ;	// restart the system
       
   256 
       
   257 		if (KErrNone != err)
       
   258 			{
       
   259 			DEBUGPRINT2(_L("Shma: RestartSystem error %d"), err);
       
   260 			PanicNow(KPanicMonitor, ERestartSystemCallFailed);
       
   261 			}
       
   262 		User::After(KDelayRequiredForRestartSys);
       
   263 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   264 		}
       
   265 	else
       
   266 		{
       
   267 		if (iStartupProperties->NoOfRetries() == 0)
       
   268 			{
       
   269 			// If NoOfRetries() == 0, execute recovery method immediately.
       
   270 			FailureRecoveryPolicy();
       
   271 			}
       
   272 		else
       
   273 			{
       
   274 			TTime curTime;
       
   275 			curTime.UniversalTime(); // current time, can be considered as the time of termination for the process
       
   276 			
       
   277 			TTime thresholdTime = (iLoadTime + TTimeIntervalMicroSeconds32(KWaitTime)); // time, till when no restart should take place
       
   278 			
       
   279 			if (curTime < thresholdTime)
       
   280 				{	
       
   281 				// Implies process terminated less than KWaitTime since the last launch of the process
       
   282 				// So to reduce Denial of Service we wait the remaining time of KWaitTime.
       
   283 	#ifdef _DEBUG
       
   284 				TPtrC fileName = iStartupProperties->FileName();
       
   285 				DEBUGPRINT2(_L("SysMonMonitor: Wait for throttle time before restarting process %S"), &(fileName));
       
   286 	#endif
       
   287 				iSysMonServer.TimerListL().AddL(thresholdTime, TCallBack(Callback, this));
       
   288 				}
       
   289 			else
       
   290 				{
       
   291 	  			 if (!HasExceededRateOfFailurePolicy())
       
   292 					RestartProcessL();
       
   293 				}
       
   294 			}
       
   295 		}
       
   296 	}
       
   297 
       
   298 
       
   299 void CMonitor::FailureRecoveryPolicy()
       
   300 	{
       
   301 	TRecoveryMethod recoveryMethod = iStartupProperties->RecoveryMethod();
       
   302 	DEBUGPRINT2(_L("SysMonMonitor: Process failed RecoveryMethod=%d"), recoveryMethod);
       
   303 	if (recoveryMethod == ERestartOS)
       
   304 		{
       
   305 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   306 		RestartSysDll(EFalse);
       
   307 #else
       
   308 		TInt err = RestartSys::RestartSystem() ;	// restart the system
       
   309 
       
   310 		if (KErrNone != err)
       
   311 			{
       
   312 			DEBUGPRINT2(_L("Shma: RestartSystem error %d"), err);
       
   313 			PanicNow(KPanicMonitor, ERestartSystemCallFailed);
       
   314 			}
       
   315 
       
   316 		User::After(KDelayRequiredForRestartSys);
       
   317 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   318 		}			
       
   319 	else if (recoveryMethod == ERestartOSWithMode)
       
   320 		{
       
   321 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   322 		RestartSysDll(ETrue, iStartupProperties->RestartMode());	// restart system in a mode
       
   323 #else
       
   324 		TInt err = RestartSys::RestartSystem(iStartupProperties->RestartMode()) ;	// restart system in a mode
       
   325 
       
   326 		if (KErrNone != err)
       
   327 			{
       
   328 			DEBUGPRINT2(_L("Shma: RestartSystem with mode error %d"), err);
       
   329 			PanicNow(KPanicMonitor, ERestartSystemCallWithMode);
       
   330 			}
       
   331 
       
   332 		User::After(KDelayRequiredForRestartSys);
       
   333 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   334 		}
       
   335 	else
       
   336 		{
       
   337 		// ignore on failure, cancel monitoring of this process
       
   338 		CancelMonitor();
       
   339 		}
       
   340 	}
       
   341 
       
   342 TBool CMonitor::HasExceededRateOfFailurePolicy()
       
   343 	{
       
   344 	if (iReLaunchAttempts > iStartupProperties->NoOfRetries())
       
   345 		{
       
   346 		// If the component's failure rate exceeds that set for the component, no new re-launch attempts will be 
       
   347 		// performed on the component and failure recovery policy will be enacted.
       
   348 		DEBUGPRINT1(_L("SysMonMonitor: Failure Recovery Policy is enacted as component's failure rate exceeded that set for the component"));
       
   349 		FailureRecoveryPolicy();
       
   350 		return ETrue;
       
   351 		}
       
   352 	else
       
   353 		return EFalse;
       
   354 	}
       
   355 
       
   356 TInt CMonitor::RunError(TInt aError)
       
   357 	{
       
   358 	DEBUGPRINT2(_L("SysMonMonitor: RunError called with error=%d, cancelling"), aError);
       
   359 	// process failed to be started, cancel monitoring of this process
       
   360 	CancelMonitor();
       
   361 	
       
   362 	// we are returning KErrNone, as the error returned by RunL() has been handled by cancelling the monitor.
       
   363 	aError = KErrNone;
       
   364 	return aError;
       
   365 	}
       
   366 
       
   367 void CMonitor::CancelMonitor()
       
   368 	{
       
   369 	DEBUGPRINT2(_L("SysMonMonitor: CMonitor cancelling monitor with iProcessId=%u"), iProcessId.Id());
       
   370 	iSysMonServer.CancelMonitor(iProcessId);
       
   371 	}
       
   372 
       
   373 void CMonitor::DecrementRelaunchAttempts()
       
   374 	{
       
   375 	 // Decrement the re-launch attempts at regular interval(interval defined by KIntervalForReLaunchRateOfFailure)
       
   376 	TInt relaunchAttempts = (iReLaunchAttempts) ? (--iReLaunchAttempts): 0;
       
   377 	TPtrC fileName = iStartupProperties->FileName();
       
   378 	DEBUGPRINT3(_L("SysMonMonitor: Decremented ReLaunch Attempts for %S to %d"), &fileName, relaunchAttempts);
       
   379 
       
   380 	if (!relaunchAttempts)
       
   381 		{
       
   382 		DEBUGPRINT2(_L("SysMonMonitor: Cancelled ReLaunch Interval Timer with processId=%u"), iProcessId.Id());
       
   383 		iReLaunchIntervalTimer->Cancel();
       
   384 		}
       
   385 	else
       
   386 		{
       
   387 		// Start the relaunch interval timer again if the relaunch attempts is greater than 0.
       
   388 		iReLaunchIntervalTimer->Start();
       
   389 		}
       
   390 	}
       
   391 
       
   392 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   393 void CMonitor::RestartSysDll(TBool aUseStartupMode, TInt aStartupMode)
       
   394 	{
       
   395 	TInt err = KErrNone;
       
   396 	if (!iRestartSysLoaded)
       
   397 		{
       
   398 		err = iRestartSysLib.Load(KCustomisedRestartSysProxyDLL);
       
   399 		// if customised restartsys dll is not provided, we try to load the default
       
   400 		// restartsys dll
       
   401 		if(KErrNotFound == err)
       
   402 			{
       
   403 			DEBUGPRINT1(_L("SysMonMonitor: Loading default restartsys.dll as custrestartsys.dll is not found"));
       
   404 			err = iRestartSysLib.Load(KRestartSysProxyDLL);
       
   405 			}
       
   406 		if(KErrNone != err)
       
   407 	 		{
       
   408 			// restartsys dll (customised or defaut) should be present for ERestartOS and ERestartOSWithMode 
       
   409 			// recovery policies we panic here if it is not present
       
   410 			DEBUGPRINT2(_L("CustRestartSys/ RestartSys failed to load - Error Code= %d"), err);
       
   411 	 		PanicNow(KPanicMonitor, ERestartSysLibNotPresent);
       
   412 	 		}
       
   413 		iRestartSysLoaded = ETrue;
       
   414 		}
       
   415 
       
   416 	if (aUseStartupMode)
       
   417 		{
       
   418 		TFuncRestartWithModeL restartSys = reinterpret_cast<TFuncRestartWithModeL>(iRestartSysLib.Lookup(1));
       
   419 		if (restartSys == NULL)
       
   420 			{
       
   421 			DEBUGPRINT1(_L("CStartSafe: Ordinal Lookup Error\n Expected Function prototype: RestartSystem(TInt aStartupMode)"));
       
   422 			User::Leave(KErrBadLibraryEntryPoint);
       
   423 			}
       
   424 		err = restartSys(aStartupMode);	// restart the system with the given startup mode
       
   425 		}
       
   426 	else
       
   427 		{
       
   428 		TFuncRestartL restartSys = reinterpret_cast<TFuncRestartL>(iRestartSysLib.Lookup(2));
       
   429 		if (restartSys == NULL)
       
   430 			{
       
   431 			DEBUGPRINT1(_L("CStartSafe: Ordinal Lookup Error\n Expected Function prototype: RestartSystem()"));
       
   432 			User::Leave(KErrBadLibraryEntryPoint);
       
   433 			}
       
   434 		err = restartSys();	// restart the system
       
   435 		}
       
   436 
       
   437 	if (KErrNone != err)
       
   438 		{
       
   439 		DEBUGPRINT2(_L("Shma: RestartSystem error %d"), err);
       
   440 		if (aStartupMode == 0)
       
   441 			{
       
   442 			PanicNow(KPanicMonitor, ERestartSystemCallFailed);
       
   443 			}
       
   444 		else
       
   445 			{
       
   446 			PanicNow(KPanicMonitor, ERestartSystemCallWithMode);
       
   447 			}
       
   448 		}
       
   449 
       
   450 	User::After(KDelayRequiredForRestartSys);
       
   451 	}
       
   452 #endif	//SYMBIAN_SSM_GRACEFUL_SHUTDOWN
       
   453 
       
   454 CRelaunchIntervalTimer* CRelaunchIntervalTimer::NewL(CMonitor& aMonitor)
       
   455 	{
       
   456 	CRelaunchIntervalTimer* self=new (ELeave) CRelaunchIntervalTimer(aMonitor);
       
   457 	CleanupStack::PushL(self);
       
   458 	self->ConstructL();
       
   459 	CleanupStack::Pop(self);
       
   460 	return self;
       
   461 	}
       
   462 
       
   463 CRelaunchIntervalTimer::~CRelaunchIntervalTimer()
       
   464 	{
       
   465 	Cancel();
       
   466 	}
       
   467 
       
   468 CRelaunchIntervalTimer::CRelaunchIntervalTimer(CMonitor& aMonitor)
       
   469 		: CTimer(EPriorityStandard), iMonitor(&aMonitor)
       
   470 	{
       
   471 	}
       
   472 
       
   473 void CRelaunchIntervalTimer::ConstructL()
       
   474 	{
       
   475 	CTimer::ConstructL();
       
   476 	CActiveScheduler::Add(this);
       
   477 	}
       
   478 
       
   479 void CRelaunchIntervalTimer::Start()
       
   480 	{
       
   481 	DEBUGPRINT1(_L("SysMonMonitor: Start the relaunch interval timer"));
       
   482 	TTime curTime;
       
   483 	curTime.UniversalTime();
       
   484 	
       
   485 	TInt intervalForReLaunchRateOfFailure = KIntervalForReLaunchRateOfFailure;
       
   486 #ifdef __WINS__
       
   487 // KIntervalForReLaunchRateOfFailure is a Rom patchable constant, so need an emulator equivalent
       
   488 // if WINS then read value from epoc.ini requires licencees to set property in epoc.ini. This value is taking in secs.
       
   489 // Usage: In epoc.ini patchdata_sysmon_exe_KIntervalForReLaunchRateOfFailure 25
       
   490 
       
   491 	TInt valueOfKIntervalForReLaunchRateOfFailure = 0;
       
   492 	if (UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"patchdata_sysmon_exe_KIntervalForReLaunchRateOfFailure",&valueOfKIntervalForReLaunchRateOfFailure) == KErrNone)
       
   493 		{
       
   494 		intervalForReLaunchRateOfFailure = valueOfKIntervalForReLaunchRateOfFailure;
       
   495 		}
       
   496 #endif
       
   497 	
       
   498 	const TTime reLaunchIntervalTime = (curTime + TTimeIntervalSeconds(intervalForReLaunchRateOfFailure));
       
   499 	AtUTC(reLaunchIntervalTime);
       
   500 	}
       
   501 
       
   502 void CRelaunchIntervalTimer::RunL()
       
   503 	{
       
   504 	iMonitor->DecrementRelaunchAttempts();
       
   505 	}
       
   506