sl@0: // Copyright (c) 2004-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 "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: // sl@0: sl@0: // system includes sl@0: #include sl@0: sl@0: // User includes sl@0: #include "SCHEXEC.H" sl@0: #include "SchLogger.h" sl@0: #include "SCHLOG.h" sl@0: #include "taskfile.h" sl@0: sl@0: //Delay ensuring this thread is be preempted allowing client cleanup sl@0: //in case task file cannot be deleted sl@0: const TInt KClientCleanupDelay = 10000; sl@0: sl@0: CTaskExecutor::CTaskExecutor(CSchLogManager& aSchLogManager) sl@0: : CActive(EPriorityStandard), sl@0: iSchLogManager(aSchLogManager) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: sl@0: CTaskExecutor::~CTaskExecutor() sl@0: { sl@0: LOGSTRING("CTaskExecutor::~CTaskExecutor - start"); sl@0: iProcess.Close(); sl@0: sl@0: // sl@0: delete iClientFileName; sl@0: delete iTaskFileName; sl@0: delete iLogErrorMessage; sl@0: LOGSTRING("CTaskExecutor::~CTaskExecutor - end"); sl@0: } sl@0: sl@0: sl@0: void CTaskExecutor::ConstructL(const TDesC& aTaskFileName, sl@0: const TDesC& aClientFileName, sl@0: const TDesC& aErrorMessage) sl@0: { sl@0: LOGSTRING("CTaskExecutor::ConstructL - start"); sl@0: // Store filename sl@0: iTaskFileName = aTaskFileName.AllocL(); sl@0: iClientFileName = aClientFileName.AllocL(); sl@0: sl@0: // In case there is an error... sl@0: iLogErrorMessage = aErrorMessage.AllocL(); sl@0: sl@0: LOGSTRING("CTaskExecutor::ConstructL - end"); sl@0: } sl@0: sl@0: sl@0: CTaskExecutor* CTaskExecutor::NewLC(const TDesC& aErrorMessage, sl@0: const TDesC& aTaskFileName, sl@0: const TDesC& aClientFileName, sl@0: CSchLogManager& aSchLogManager) sl@0: { sl@0: LOGSTRING("CTaskExecutor::NewLC"); sl@0: CTaskExecutor* self = new(ELeave) CTaskExecutor(aSchLogManager); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aTaskFileName, aClientFileName, aErrorMessage); sl@0: return self; sl@0: } sl@0: sl@0: void CTaskExecutor::RunL() sl@0: { sl@0: LOGSTRING3("CTaskExecutor::RunL - task finished running [client: %S, task: %S]", iClientFileName, iTaskFileName); sl@0: // sl@0: // RunL is called when the process/thread terminates sl@0: // so that any error conditions can be handled. sl@0: TInt exitReason = iProcess.ExitReason(); sl@0: LOGSTRING2("CTaskExecutor::RunL - process exit reason was: %d", exitReason); sl@0: sl@0: // Close the process/thread sl@0: iProcess.Close(); sl@0: sl@0: // Check for error code sl@0: if (exitReason != KErrNone) sl@0: { sl@0: // Submit a log entry to record the error. sl@0: LOGSTRING2("CTaskExecutor::RunL - recording unclean process exit (%d) in the log engine", exitReason); sl@0: if(iLogErrorMessage) sl@0: iSchLogManager.LogError(*iLogErrorMessage,exitReason); sl@0: else sl@0: iSchLogManager.LogError(exitReason); sl@0: } sl@0: sl@0: // Clean up the file. Only delete it here once task process has finished. sl@0: // If task process never started then file is deleted in CClientProxy code. sl@0: User::LeaveIfError(iFsSession.Connect()); sl@0: CleanupClosePushL(iFsSession); sl@0: sl@0: TInt fileDeleteErr = iFsSession.Delete(*iTaskFileName); sl@0: sl@0: // If unable to delete file wait and try again sl@0: if (fileDeleteErr != KErrNone) sl@0: { sl@0: sl@0: //Allow thread to be preempted to allow for cleanup of iProcess sl@0: User::After(KClientCleanupDelay); sl@0: sl@0: fileDeleteErr = iFsSession.Delete(*iTaskFileName); sl@0: sl@0: // If still unable to delete file record the fact sl@0: if (fileDeleteErr != KErrNone) sl@0: { sl@0: if(iLogErrorMessage) sl@0: { sl@0: iSchLogManager.LogError(*iLogErrorMessage, fileDeleteErr); sl@0: } sl@0: else sl@0: { sl@0: iSchLogManager.LogError(fileDeleteErr); sl@0: } sl@0: } sl@0: } sl@0: sl@0: //Calls iFsSession::Close() so no need to call explicitly sl@0: CleanupStack::PopAndDestroy(); sl@0: sl@0: // Delete outselves since we've finished sl@0: LOGSTRING("CTaskExecutor::RunL - deleting ourself"); sl@0: delete this; sl@0: } sl@0: sl@0: void CTaskExecutor::DoCancel() sl@0: { sl@0: LOGSTRING("CTaskExecutor::DoCancel - start"); sl@0: iProcess.LogonCancel(iStatus); sl@0: // Delete file and ourselves since we can't do anything else. sl@0: // We are in a bad state if we reach here but at least make the most of it. sl@0: LOGSTRING("CTaskExecutor::DoCancel - deleting ourself"); sl@0: sl@0: //Connect to file session sl@0: TInt err = iFsSession.Connect(); sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: err = iFsSession.Delete(*iTaskFileName); sl@0: } sl@0: sl@0: // If unable to delete file record the fact sl@0: if (err != KErrNone) sl@0: { sl@0: if(iLogErrorMessage) sl@0: { sl@0: iSchLogManager.LogError(*iLogErrorMessage, err); sl@0: } sl@0: else sl@0: { sl@0: iSchLogManager.LogError(err); sl@0: } sl@0: } sl@0: sl@0: //Close the file session sl@0: iFsSession.Close(); sl@0: sl@0: delete this; sl@0: LOGSTRING("CTaskExecutor::DoCancel - end"); sl@0: } sl@0: sl@0: void CTaskExecutor::ExecuteL() sl@0: { sl@0: // If this leaves, CClientProxy should handle error.... sl@0: // CTaskScheduler::ExecuteClients() traps the leave and then calls sl@0: // CClientProxy::FailToExecute() to handle the error. sl@0: #ifdef __SCHLOGGING__ sl@0: { sl@0: TTime time; time.HomeTime(); sl@0: TDateTime due = time.DateTime(); sl@0: 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()); sl@0: } sl@0: #endif sl@0: sl@0: // Create a new process and pass the name of the task file as the command line argument sl@0: // (data for the target exe). sl@0: LOGSTRING("CTaskExecutor::ExecuteL - creating process"); sl@0: TInt err = iProcess.Create(*iClientFileName, KNullDesC); sl@0: sl@0: // Will check the error, report the problem and leave (if err