1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericservices/taskscheduler/SCHSVR/SCHEXEC.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,237 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +// system includes
1.20 +#include <schtask.h>
1.21 +
1.22 +// User includes
1.23 +#include "SCHEXEC.H"
1.24 +#include "SchLogger.h"
1.25 +#include "SCHLOG.h"
1.26 +#include "taskfile.h"
1.27 +
1.28 +//Delay ensuring this thread is be preempted allowing client cleanup
1.29 +//in case task file cannot be deleted
1.30 +const TInt KClientCleanupDelay = 10000;
1.31 +
1.32 +CTaskExecutor::CTaskExecutor(CSchLogManager& aSchLogManager)
1.33 +: CActive(EPriorityStandard),
1.34 + iSchLogManager(aSchLogManager)
1.35 + {
1.36 + CActiveScheduler::Add(this);
1.37 + }
1.38 +
1.39 +
1.40 +CTaskExecutor::~CTaskExecutor()
1.41 + {
1.42 + LOGSTRING("CTaskExecutor::~CTaskExecutor - start");
1.43 + iProcess.Close();
1.44 +
1.45 + //
1.46 + delete iClientFileName;
1.47 + delete iTaskFileName;
1.48 + delete iLogErrorMessage;
1.49 + LOGSTRING("CTaskExecutor::~CTaskExecutor - end");
1.50 + }
1.51 +
1.52 +
1.53 +void CTaskExecutor::ConstructL(const TDesC& aTaskFileName,
1.54 + const TDesC& aClientFileName,
1.55 + const TDesC& aErrorMessage)
1.56 + {
1.57 + LOGSTRING("CTaskExecutor::ConstructL - start");
1.58 + // Store filename
1.59 + iTaskFileName = aTaskFileName.AllocL();
1.60 + iClientFileName = aClientFileName.AllocL();
1.61 +
1.62 + // In case there is an error...
1.63 + iLogErrorMessage = aErrorMessage.AllocL();
1.64 +
1.65 + LOGSTRING("CTaskExecutor::ConstructL - end");
1.66 + }
1.67 +
1.68 +
1.69 +CTaskExecutor* CTaskExecutor::NewLC(const TDesC& aErrorMessage,
1.70 + const TDesC& aTaskFileName,
1.71 + const TDesC& aClientFileName,
1.72 + CSchLogManager& aSchLogManager)
1.73 + {
1.74 + LOGSTRING("CTaskExecutor::NewLC");
1.75 + CTaskExecutor* self = new(ELeave) CTaskExecutor(aSchLogManager);
1.76 + CleanupStack::PushL(self);
1.77 + self->ConstructL(aTaskFileName, aClientFileName, aErrorMessage);
1.78 + return self;
1.79 + }
1.80 +
1.81 +void CTaskExecutor::RunL()
1.82 + {
1.83 + LOGSTRING3("CTaskExecutor::RunL - task finished running [client: %S, task: %S]", iClientFileName, iTaskFileName);
1.84 + //
1.85 + // RunL is called when the process/thread terminates
1.86 + // so that any error conditions can be handled.
1.87 + TInt exitReason = iProcess.ExitReason();
1.88 + LOGSTRING2("CTaskExecutor::RunL - process exit reason was: %d", exitReason);
1.89 +
1.90 + // Close the process/thread
1.91 + iProcess.Close();
1.92 +
1.93 + // Check for error code
1.94 + if (exitReason != KErrNone)
1.95 + {
1.96 + // Submit a log entry to record the error.
1.97 + LOGSTRING2("CTaskExecutor::RunL - recording unclean process exit (%d) in the log engine", exitReason);
1.98 + if(iLogErrorMessage)
1.99 + iSchLogManager.LogError(*iLogErrorMessage,exitReason);
1.100 + else
1.101 + iSchLogManager.LogError(exitReason);
1.102 + }
1.103 +
1.104 + // Clean up the file. Only delete it here once task process has finished.
1.105 + // If task process never started then file is deleted in CClientProxy code.
1.106 + User::LeaveIfError(iFsSession.Connect());
1.107 + CleanupClosePushL(iFsSession);
1.108 +
1.109 + TInt fileDeleteErr = iFsSession.Delete(*iTaskFileName);
1.110 +
1.111 + // If unable to delete file wait and try again
1.112 + if (fileDeleteErr != KErrNone)
1.113 + {
1.114 +
1.115 + //Allow thread to be preempted to allow for cleanup of iProcess
1.116 + User::After(KClientCleanupDelay);
1.117 +
1.118 + fileDeleteErr = iFsSession.Delete(*iTaskFileName);
1.119 +
1.120 + // If still unable to delete file record the fact
1.121 + if (fileDeleteErr != KErrNone)
1.122 + {
1.123 + if(iLogErrorMessage)
1.124 + {
1.125 + iSchLogManager.LogError(*iLogErrorMessage, fileDeleteErr);
1.126 + }
1.127 + else
1.128 + {
1.129 + iSchLogManager.LogError(fileDeleteErr);
1.130 + }
1.131 + }
1.132 + }
1.133 +
1.134 + //Calls iFsSession::Close() so no need to call explicitly
1.135 + CleanupStack::PopAndDestroy();
1.136 +
1.137 + // Delete outselves since we've finished
1.138 + LOGSTRING("CTaskExecutor::RunL - deleting ourself");
1.139 + delete this;
1.140 + }
1.141 +
1.142 +void CTaskExecutor::DoCancel()
1.143 + {
1.144 + LOGSTRING("CTaskExecutor::DoCancel - start");
1.145 + iProcess.LogonCancel(iStatus);
1.146 + // Delete file and ourselves since we can't do anything else.
1.147 + // We are in a bad state if we reach here but at least make the most of it.
1.148 + LOGSTRING("CTaskExecutor::DoCancel - deleting ourself");
1.149 +
1.150 + //Connect to file session
1.151 + TInt err = iFsSession.Connect();
1.152 +
1.153 + if(err == KErrNone)
1.154 + {
1.155 + err = iFsSession.Delete(*iTaskFileName);
1.156 + }
1.157 +
1.158 + // If unable to delete file record the fact
1.159 + if (err != KErrNone)
1.160 + {
1.161 + if(iLogErrorMessage)
1.162 + {
1.163 + iSchLogManager.LogError(*iLogErrorMessage, err);
1.164 + }
1.165 + else
1.166 + {
1.167 + iSchLogManager.LogError(err);
1.168 + }
1.169 + }
1.170 +
1.171 + //Close the file session
1.172 + iFsSession.Close();
1.173 +
1.174 + delete this;
1.175 + LOGSTRING("CTaskExecutor::DoCancel - end");
1.176 + }
1.177 +
1.178 +void CTaskExecutor::ExecuteL()
1.179 + {
1.180 + // If this leaves, CClientProxy should handle error....
1.181 + // CTaskScheduler::ExecuteClients() traps the leave and then calls
1.182 + // CClientProxy::FailToExecute() to handle the error.
1.183 +#ifdef __SCHLOGGING__
1.184 + {
1.185 + TTime time; time.HomeTime();
1.186 + TDateTime due = time.DateTime();
1.187 + 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());
1.188 + }
1.189 +#endif
1.190 +
1.191 + // Create a new process and pass the name of the task file as the command line argument
1.192 + // (data for the target exe).
1.193 + LOGSTRING("CTaskExecutor::ExecuteL - creating process");
1.194 + TInt err = iProcess.Create(*iClientFileName, KNullDesC);
1.195 +
1.196 + // Will check the error, report the problem and leave (if err<KErrNone)
1.197 + // otherwise does nothing.
1.198 + LOGSTRING("CTaskExecutor::ExecuteL - checking process creation error code");
1.199 + CheckErrorAndLeaveL(err);
1.200 +
1.201 + // connect to new file session to avoid possible security
1.202 + // consequences if lauched process tries to use passed file in
1.203 + // subversive way.
1.204 + User::LeaveIfError(iFsSession.Connect());
1.205 + CleanupClosePushL(iFsSession);
1.206 + User::LeaveIfError(iFsSession.ShareProtected());
1.207 +
1.208 + User::LeaveIfError(iTaskFile.Open(iFsSession, *iTaskFileName, EFileRead));
1.209 + CleanupClosePushL(iTaskFile);
1.210 +
1.211 + // transfer file handle to launched process
1.212 + err = iTaskFile.TransferToProcess(iProcess, KTaskFsHandleIndex, KTaskFileHandleIndex);
1.213 +
1.214 + //Close task file and session handles
1.215 + //Calls iFsSession::Close() and iTaskFile::Close() so no need to call explicitly
1.216 + CleanupStack::PopAndDestroy(2);
1.217 +
1.218 + CheckErrorAndLeaveL(err);
1.219 +
1.220 + // Asynchronous logon: completes when process terminates with process exit code
1.221 + iProcess.Logon(iStatus);
1.222 + iProcess.Resume();
1.223 +
1.224 + SetActive();
1.225 + LOGSTRING("CTaskExecutor::ExecuteL - end");
1.226 +
1.227 + }
1.228 +
1.229 +void CTaskExecutor::CheckErrorAndLeaveL(TInt aError)
1.230 + {
1.231 + if (aError < KErrNone)
1.232 + {
1.233 + if(iLogErrorMessage)
1.234 + iSchLogManager.LogError(*iLogErrorMessage,aError);
1.235 + else
1.236 + iSchLogManager.LogError(aError);
1.237 + User::Leave(aError);
1.238 + }
1.239 + }
1.240 +