diff -r 000000000000 -r bde4ae8d615e os/ossrv/genericservices/taskscheduler/SCHSVR/SCHEXEC.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/genericservices/taskscheduler/SCHSVR/SCHEXEC.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,237 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +// system includes +#include + +// User includes +#include "SCHEXEC.H" +#include "SchLogger.h" +#include "SCHLOG.h" +#include "taskfile.h" + +//Delay ensuring this thread is be preempted allowing client cleanup +//in case task file cannot be deleted +const TInt KClientCleanupDelay = 10000; + +CTaskExecutor::CTaskExecutor(CSchLogManager& aSchLogManager) +: CActive(EPriorityStandard), + iSchLogManager(aSchLogManager) + { + CActiveScheduler::Add(this); + } + + +CTaskExecutor::~CTaskExecutor() + { + LOGSTRING("CTaskExecutor::~CTaskExecutor - start"); + iProcess.Close(); + + // + delete iClientFileName; + delete iTaskFileName; + delete iLogErrorMessage; + LOGSTRING("CTaskExecutor::~CTaskExecutor - end"); + } + + +void CTaskExecutor::ConstructL(const TDesC& aTaskFileName, + const TDesC& aClientFileName, + const TDesC& aErrorMessage) + { + LOGSTRING("CTaskExecutor::ConstructL - start"); + // Store filename + iTaskFileName = aTaskFileName.AllocL(); + iClientFileName = aClientFileName.AllocL(); + + // In case there is an error... + iLogErrorMessage = aErrorMessage.AllocL(); + + LOGSTRING("CTaskExecutor::ConstructL - end"); + } + + +CTaskExecutor* CTaskExecutor::NewLC(const TDesC& aErrorMessage, + const TDesC& aTaskFileName, + const TDesC& aClientFileName, + CSchLogManager& aSchLogManager) + { + LOGSTRING("CTaskExecutor::NewLC"); + CTaskExecutor* self = new(ELeave) CTaskExecutor(aSchLogManager); + CleanupStack::PushL(self); + self->ConstructL(aTaskFileName, aClientFileName, aErrorMessage); + return self; + } + +void CTaskExecutor::RunL() + { + LOGSTRING3("CTaskExecutor::RunL - task finished running [client: %S, task: %S]", iClientFileName, iTaskFileName); + // + // RunL is called when the process/thread terminates + // so that any error conditions can be handled. + TInt exitReason = iProcess.ExitReason(); + LOGSTRING2("CTaskExecutor::RunL - process exit reason was: %d", exitReason); + + // Close the process/thread + iProcess.Close(); + + // Check for error code + if (exitReason != KErrNone) + { + // Submit a log entry to record the error. + LOGSTRING2("CTaskExecutor::RunL - recording unclean process exit (%d) in the log engine", exitReason); + if(iLogErrorMessage) + iSchLogManager.LogError(*iLogErrorMessage,exitReason); + else + iSchLogManager.LogError(exitReason); + } + + // Clean up the file. Only delete it here once task process has finished. + // If task process never started then file is deleted in CClientProxy code. + User::LeaveIfError(iFsSession.Connect()); + CleanupClosePushL(iFsSession); + + TInt fileDeleteErr = iFsSession.Delete(*iTaskFileName); + + // If unable to delete file wait and try again + if (fileDeleteErr != KErrNone) + { + + //Allow thread to be preempted to allow for cleanup of iProcess + User::After(KClientCleanupDelay); + + fileDeleteErr = iFsSession.Delete(*iTaskFileName); + + // If still unable to delete file record the fact + if (fileDeleteErr != KErrNone) + { + if(iLogErrorMessage) + { + iSchLogManager.LogError(*iLogErrorMessage, fileDeleteErr); + } + else + { + iSchLogManager.LogError(fileDeleteErr); + } + } + } + + //Calls iFsSession::Close() so no need to call explicitly + CleanupStack::PopAndDestroy(); + + // Delete outselves since we've finished + LOGSTRING("CTaskExecutor::RunL - deleting ourself"); + delete this; + } + +void CTaskExecutor::DoCancel() + { + LOGSTRING("CTaskExecutor::DoCancel - start"); + iProcess.LogonCancel(iStatus); + // Delete file and ourselves since we can't do anything else. + // We are in a bad state if we reach here but at least make the most of it. + LOGSTRING("CTaskExecutor::DoCancel - deleting ourself"); + + //Connect to file session + TInt err = iFsSession.Connect(); + + if(err == KErrNone) + { + err = iFsSession.Delete(*iTaskFileName); + } + + // If unable to delete file record the fact + if (err != KErrNone) + { + if(iLogErrorMessage) + { + iSchLogManager.LogError(*iLogErrorMessage, err); + } + else + { + iSchLogManager.LogError(err); + } + } + + //Close the file session + iFsSession.Close(); + + delete this; + LOGSTRING("CTaskExecutor::DoCancel - end"); + } + +void CTaskExecutor::ExecuteL() + { + // If this leaves, CClientProxy should handle error.... + // CTaskScheduler::ExecuteClients() traps the leave and then calls + // CClientProxy::FailToExecute() to handle the error. +#ifdef __SCHLOGGING__ + { + TTime time; time.HomeTime(); + TDateTime due = time.DateTime(); + 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()); + } +#endif + + // Create a new process and pass the name of the task file as the command line argument + // (data for the target exe). + LOGSTRING("CTaskExecutor::ExecuteL - creating process"); + TInt err = iProcess.Create(*iClientFileName, KNullDesC); + + // Will check the error, report the problem and leave (if err