genericservices/taskscheduler/SCHSVR/SCHEXEC.CPP
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2004-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 // system includes
       
    17 #include <schtask.h>
       
    18 
       
    19 // User includes
       
    20 #include "SCHEXEC.H"
       
    21 #include "SchLogger.h"
       
    22 #include "SCHLOG.h"
       
    23 #include "taskfile.h"
       
    24 
       
    25 //Delay ensuring this thread is be preempted allowing client cleanup
       
    26 //in case task file cannot be deleted
       
    27 const TInt KClientCleanupDelay = 10000;
       
    28 
       
    29 CTaskExecutor::CTaskExecutor(CSchLogManager& aSchLogManager)
       
    30 :	CActive(EPriorityStandard), 
       
    31 	iSchLogManager(aSchLogManager)
       
    32 	{
       
    33 	CActiveScheduler::Add(this);
       
    34 	}
       
    35 
       
    36 
       
    37 CTaskExecutor::~CTaskExecutor()
       
    38 	{
       
    39 	LOGSTRING("CTaskExecutor::~CTaskExecutor - start");
       
    40 	iProcess.Close();
       
    41 
       
    42 	//
       
    43 	delete iClientFileName;
       
    44 	delete iTaskFileName;
       
    45 	delete iLogErrorMessage;
       
    46 	LOGSTRING("CTaskExecutor::~CTaskExecutor - end");
       
    47 	}
       
    48 
       
    49 
       
    50 void CTaskExecutor::ConstructL(const TDesC& aTaskFileName, 
       
    51 								const TDesC& aClientFileName, 
       
    52 								const TDesC& aErrorMessage)
       
    53 	{
       
    54 	LOGSTRING("CTaskExecutor::ConstructL - start");
       
    55 	// Store filename
       
    56 	iTaskFileName = aTaskFileName.AllocL();
       
    57 	iClientFileName = aClientFileName.AllocL();
       
    58 
       
    59 	// In case there is an error...
       
    60 	iLogErrorMessage = aErrorMessage.AllocL();
       
    61 	
       
    62 	LOGSTRING("CTaskExecutor::ConstructL - end");
       
    63 	}
       
    64 
       
    65 
       
    66 CTaskExecutor* CTaskExecutor::NewLC(const TDesC& aErrorMessage, 
       
    67 									const TDesC& aTaskFileName, 
       
    68 									const TDesC& aClientFileName,
       
    69 									CSchLogManager& aSchLogManager)
       
    70 	{
       
    71 	LOGSTRING("CTaskExecutor::NewLC");
       
    72 	CTaskExecutor* self = new(ELeave) CTaskExecutor(aSchLogManager);
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL(aTaskFileName,	aClientFileName, aErrorMessage);
       
    75     return self;
       
    76 	}
       
    77 
       
    78 void CTaskExecutor::RunL()
       
    79 	{
       
    80 	LOGSTRING3("CTaskExecutor::RunL - task finished running [client: %S, task: %S]", iClientFileName, iTaskFileName);
       
    81 	//
       
    82 	// RunL is called when the process/thread terminates
       
    83 	// so that any error conditions can be handled.
       
    84 	TInt exitReason = iProcess.ExitReason();
       
    85 	LOGSTRING2("CTaskExecutor::RunL - process exit reason was: %d", exitReason);
       
    86 
       
    87 	// Close the process/thread
       
    88 	iProcess.Close();
       
    89 	
       
    90 	// Check for error code
       
    91 	if	(exitReason != KErrNone)
       
    92 		{
       
    93 		// Submit a log entry to record the error. 
       
    94 		LOGSTRING2("CTaskExecutor::RunL - recording unclean process exit (%d) in the log engine", exitReason);
       
    95 		if(iLogErrorMessage)
       
    96 			iSchLogManager.LogError(*iLogErrorMessage,exitReason);
       
    97 		else
       
    98 			iSchLogManager.LogError(exitReason);			
       
    99 		}
       
   100 
       
   101 	// Clean up the file.  Only delete it here once task process has finished.
       
   102 	// If task process never started then file is deleted in CClientProxy code.
       
   103 	User::LeaveIfError(iFsSession.Connect());
       
   104 	CleanupClosePushL(iFsSession);
       
   105 	
       
   106 	TInt fileDeleteErr = iFsSession.Delete(*iTaskFileName);
       
   107 
       
   108 	// If unable to delete file wait and try again
       
   109 	if (fileDeleteErr != KErrNone)
       
   110 		{
       
   111 		
       
   112 		//Allow thread to be preempted to allow for cleanup of iProcess
       
   113 		User::After(KClientCleanupDelay);
       
   114 		
       
   115 		fileDeleteErr = iFsSession.Delete(*iTaskFileName);
       
   116 			
       
   117 		// If still unable to delete file record the fact
       
   118 		if (fileDeleteErr != KErrNone)
       
   119 			{				
       
   120 			if(iLogErrorMessage)
       
   121 				{		
       
   122 				iSchLogManager.LogError(*iLogErrorMessage, fileDeleteErr);
       
   123 				}
       
   124 			else
       
   125 				{
       
   126 				iSchLogManager.LogError(fileDeleteErr);
       
   127 				}				
       
   128 			}
       
   129 		}
       
   130 		
       
   131 	//Calls iFsSession::Close() so no need to call explicitly
       
   132 	CleanupStack::PopAndDestroy();
       
   133 
       
   134 	// Delete outselves since we've finished
       
   135 	LOGSTRING("CTaskExecutor::RunL - deleting ourself");
       
   136 	delete this;
       
   137 	}	
       
   138 
       
   139 void CTaskExecutor::DoCancel()
       
   140 	{
       
   141 	LOGSTRING("CTaskExecutor::DoCancel - start");
       
   142 	iProcess.LogonCancel(iStatus);
       
   143 	// Delete file and ourselves since we can't do anything else.
       
   144 	// We are in a bad state if we reach here but at least make the most of it.
       
   145 	LOGSTRING("CTaskExecutor::DoCancel - deleting ourself");
       
   146 	
       
   147 	//Connect to file session
       
   148 	TInt err = iFsSession.Connect();
       
   149 	
       
   150 	if(err == KErrNone)
       
   151 		{
       
   152 		err = iFsSession.Delete(*iTaskFileName);
       
   153 		}
       
   154 	
       
   155 	// If unable to delete file record the fact
       
   156 	if (err != KErrNone)
       
   157 		{
       
   158 		if(iLogErrorMessage)
       
   159 			{
       
   160 			iSchLogManager.LogError(*iLogErrorMessage, err);
       
   161 			}
       
   162 		else
       
   163 			{
       
   164 			iSchLogManager.LogError(err);
       
   165 			}
       
   166 		}
       
   167 		
       
   168 	//Close the file session
       
   169 	iFsSession.Close();
       
   170 	
       
   171 	delete this;
       
   172 	LOGSTRING("CTaskExecutor::DoCancel - end");
       
   173 	}	
       
   174 
       
   175 void CTaskExecutor::ExecuteL()
       
   176 	{
       
   177 	// If this leaves, CClientProxy should handle error....
       
   178 	// CTaskScheduler::ExecuteClients() traps the leave and then calls
       
   179 	// CClientProxy::FailToExecute() to handle the error.
       
   180 #ifdef __SCHLOGGING__
       
   181 	{
       
   182 	TTime time; time.HomeTime();
       
   183 	TDateTime due = time.DateTime();
       
   184 	LOGSTRING8("CTaskExecutor::ExecuteL - Executing tasks at: [%02d/%02d/%d] @ %02d:%02d:%02d.%05d", due.Day(), (TInt) due.Month() + 1, due.Year(), due.Hour(), due.Minute(), due.Second(), due.MicroSecond());
       
   185 	}
       
   186 #endif
       
   187 
       
   188 	// Create a new process and pass the name of the task file as the command line argument
       
   189 	// (data for the target exe).
       
   190 	LOGSTRING("CTaskExecutor::ExecuteL - creating process");
       
   191 	TInt err = iProcess.Create(*iClientFileName, KNullDesC);
       
   192 	
       
   193 	// Will check the error, report the problem and leave (if err<KErrNone)
       
   194 	// otherwise does nothing.
       
   195 	LOGSTRING("CTaskExecutor::ExecuteL - checking process creation error code");
       
   196 	CheckErrorAndLeaveL(err);
       
   197 	
       
   198 	// connect to new file session to avoid possible security
       
   199 	// consequences if lauched process tries to use passed file in
       
   200 	// subversive way.
       
   201 	User::LeaveIfError(iFsSession.Connect());
       
   202 	CleanupClosePushL(iFsSession);
       
   203 	User::LeaveIfError(iFsSession.ShareProtected());
       
   204 	
       
   205 	User::LeaveIfError(iTaskFile.Open(iFsSession, *iTaskFileName, EFileRead));
       
   206 	CleanupClosePushL(iTaskFile);
       
   207 	
       
   208 	// transfer file handle to launched process
       
   209 	err = iTaskFile.TransferToProcess(iProcess, KTaskFsHandleIndex, KTaskFileHandleIndex);
       
   210 
       
   211 	//Close task file and session handles
       
   212 	//Calls iFsSession::Close() and iTaskFile::Close() so no need to call explicitly
       
   213 	CleanupStack::PopAndDestroy(2);
       
   214 	
       
   215 	CheckErrorAndLeaveL(err);
       
   216 
       
   217 	// Asynchronous logon: completes when process terminates with process exit code
       
   218 	iProcess.Logon(iStatus);
       
   219 	iProcess.Resume();
       
   220 
       
   221 	SetActive();
       
   222 	LOGSTRING("CTaskExecutor::ExecuteL - end");
       
   223 
       
   224 	}
       
   225 
       
   226 void CTaskExecutor::CheckErrorAndLeaveL(TInt aError)
       
   227 	{
       
   228 	if	(aError < KErrNone)
       
   229 		{
       
   230 		if(iLogErrorMessage)
       
   231 			iSchLogManager.LogError(*iLogErrorMessage,aError);
       
   232 		else
       
   233 			iSchLogManager.LogError(aError);			
       
   234 		User::Leave(aError);
       
   235 		}
       
   236 	}
       
   237