--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestServer/src/Testundertaker.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,492 @@
+/*
+* Copyright (c) 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: This module contains implementation of CUnderTaker
+* class member functions. CUnderTaker is a class, which listens
+* on Test Execution Thread death, and if that thread dies, then
+* UnderTaker aborts the ongoing test execution request.
+*
+*/
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <e32svr.h>
+#include "TestEngineClient.h"
+#include <StifTestModule.h>
+#include <stifinternal/TestServerClient.h>
+#include "TestServer.h"
+#include "TestServerModuleIf.h"
+#include "TestServerCommon.h"
+#include "PrintQueue.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ==================== LOCAL FUNCTIONS =======================================
+
+// ================= MEMBER FUNCTIONS =========================================
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: NewL
+
+ Description: Constructs a new CUnderTaker object.
+
+ Parameters: CTestModuleContainer* aContainer :in: "Parent"
+
+ Return Values: CUnderTaker* New undertaker
+
+ Errors/Exceptions: Leaves if memory allocation or ConstructL leaves.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CUnderTaker* CUnderTaker::NewL( CTestModuleContainer* aContainer )
+ {
+
+ CUnderTaker* self = new( ELeave ) CUnderTaker();
+ CleanupStack::PushL( self );
+ self->ConstructL( aContainer );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: ConstructL
+
+ Description: Second level constructor.
+
+ Parameters: CTestModuleContainer* aExecution :in: "Parent"
+
+ Return Values: None
+
+ Errors/Exceptions: Panics if aContainer is NULL
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CUnderTaker::ConstructL( CTestModuleContainer* aContainer )
+ {
+
+ __ASSERT_ALWAYS( aContainer,
+ CTestServer::PanicServer( ENullTestModuleContainer ) );
+
+ iModuleContainer = aContainer;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: CUnderTaker
+
+ Description: Constructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CUnderTaker::CUnderTaker() :
+ CActive( CActive::EPriorityHigh+1 )
+ {
+
+ // By default in asynchronous mode
+ iSynchronousMode = EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: ~CUnderTaker
+
+ Description: Destructor.
+ Cancels active request.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CUnderTaker::~CUnderTaker()
+ {
+
+ Cancel();
+
+ }
+
+
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: StartL
+
+ Description: Starts to monitor thread.
+
+ Parameters: None
+
+ Return Values: TInt Always KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CUnderTaker::StartL()
+ {
+
+ SetActive();
+ iModuleContainer->iThread.Logon( iStatus );
+ iCancelNeeded = ETrue;
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: RunL
+
+ Description: Handles thread death.
+ Function does:
+ 1 ) Stops monitoring thread
+ 1 ) Marks thread death
+ 2 ) Completes ongoing requests
+ 3 ) Cleans the memory
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CUnderTaker::RunL()
+ {
+
+ // Make sure that any of the test interference thread's won't stay to run.
+ iModuleContainer->KillTestinterferenceThread();
+
+ // Make sure that any of the test measurement's process won't stay to run.
+ iModuleContainer->KillTestMeasurement();
+
+ // Get the exit category
+ TName exitCategory = _L( "Crash reason:" );
+ exitCategory.Append( iModuleContainer->iThread.ExitCategory() );
+ TInt exitReason = iModuleContainer->iThread.ExitReason();
+ TFullTestResult::TCaseExecutionResult exitType = TFullTestResult::ECaseException;
+ if( iModuleContainer->iThread.ExitType() == EExitPanic )
+ {
+ exitType = TFullTestResult::ECasePanic;
+ }
+
+ // it is not running anymore..
+ iModuleContainer->iUpAndRunning = EFalse;
+
+ // Do not monitor anymore.
+ iModuleContainer->iThread.LogonCancel( iStatus );
+ iCancelNeeded = EFalse;
+
+ __TRACE( KError,( CStifLogger::ERed, _L( "Execution thread crashed, exitReason = %d" ), exitReason ) );
+ __TRACE( KError,( CStifLogger::ERed, exitCategory ) );
+
+ if ( iSynchronousMode )
+ {
+
+ // Synchronous request was running. Complete that
+ // operation.
+ __TRACE( KVerbose,( _L( "CUnderTaker::RunL Crash during synchronous operation" ) ) );
+ iModuleContainer->iErrorResult = KErrDied;
+ iModuleContainer->Cancel();
+ iModuleContainer->iUpAndRunning = EFalse;
+
+ // Print notification
+ TName operationText = _L("Test module died when calling:");
+ operationText.Append( iModuleContainer->iOperationText );
+
+ // Print to log file
+ __TRACE( KError,( CStifLogger::ERed, operationText ) );
+ // Print to UI
+ iModuleContainer->iCTestModule->ErrorPrint ( 1, operationText );
+
+ // Stop active scheduler.
+ CActiveScheduler::Stop();
+
+ // Execution continues from CTestModuleContainer::StartAndWaitOperation.
+
+ }
+ else
+ {// Test case was running,
+
+ __TRACE( KError,( _L( "Test case execution aborted" ) ) );
+ __TRACE( KVerbose,( _L( "CUnderTaker::Run crash during test execution" ) ) );
+
+ TInt caseResult = KErrGeneral;
+
+ // Check if case have any special panic or exception codes that are "passed"
+ if ( iModuleContainer->iAllowedExitReason !=
+ CTestModuleIf::ENormal )
+ {
+
+ if ( iModuleContainer->iAllowedExitReason ==
+ CTestModuleIf::EPanic &&
+ exitType == TFullTestResult::ECasePanic &&
+ iModuleContainer->iAllowedExitCode == exitReason )
+ {
+ exitType = TFullTestResult::ECaseExecuted;
+ caseResult = KErrNone;
+ exitCategory = _L("Allowed case panic");
+
+ __TRACE( KError,( _L( "Test case execution panic, setting to OK" ) ) );
+ }
+
+ if ( iModuleContainer->iAllowedExitReason ==
+ CTestModuleIf::EException &&
+ exitType == TFullTestResult::ECaseException &&
+ iModuleContainer->iAllowedExitCode == exitReason )
+ {
+ exitType = TFullTestResult::ECaseExecuted;
+ caseResult = KErrNone;
+ exitCategory = _L("Allowed case exception");
+
+ __TRACE( KError,( _L( "Test case execution exception, setting to OK" ) ) );
+ }
+
+
+ }
+
+ // This was asynchronous request, and nobody is waiting for it
+ // completion in server, so all clean-up must be done here
+
+ // Forget iTestThreadContainer pointer, memory is freed because test thread
+ // is destroyed
+ // This is needed to prevent from accessing memory from thread that is destroyed.
+ // Do this only if test is been executed.
+ iModuleContainer->iThreadContainer = NULL;
+
+ if (iModuleContainer->iCTestExecution != NULL)
+ {
+ // Execution thread have been killed
+ iModuleContainer->iCTestExecution->SetThreadState( CTestExecution::ECancelled );
+
+
+ // Cancel the request
+ iModuleContainer->iCTestExecution->CompleteTestExecution( KErrNone,
+ exitType,
+ exitReason,
+ caseResult,
+ exitCategory );
+
+ // If the print queue is empty, and there is active print
+ // request, then cancel that request.
+ // NOTE: Case queue not empty AND request waiting AND
+ // thread terminated can't happen due iPrintMutex
+ iModuleContainer->iCTestExecution->CompletePrintRequestIfQueueEmpty();
+ }
+ else
+ {
+ __TRACE( KError,( _L( "STIF internal error - iCTestExecution is NULL in CUnderTaker::RunL." ) ) );
+ User::Leave(KErrGeneral);
+ }
+ // Free the memory
+ // Remove undertaker from module container to make sure that
+ // it does not delete this.
+ iModuleContainer->iUnderTaker = NULL;
+ delete iModuleContainer;
+ iModuleContainer = NULL;
+
+ // Suicide. "Parent", i.e iModuleContainer has already died
+ // and no-one have pointer to this active object, so die.
+ delete this;
+
+ }
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: DoCancel
+
+ Description: Stops thread monitoring
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+void CUnderTaker::DoCancel()
+ {
+
+ if( iCancelNeeded && iModuleContainer )
+ {
+ iModuleContainer->iThread.LogonCancel( iStatus );
+ }
+ else
+ {
+ // Note that iModuleContainer can be NULL if iCancelNeeded is EFalse
+ __ASSERT_ALWAYS( iModuleContainer,
+ CTestServer::PanicServer( ENullTestModuleContainer ) );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: RunError
+
+ Description: Handle errors. RunL function does not leave, so one should
+ never come here.
+
+ Print trace and let framework handle error( i.e to do Panic )
+
+ Parameters: TInt aError: :in: Error code
+
+ Return Values: TInt Error code
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CUnderTaker::RunError( TInt aError )
+ {
+ __TRACE( KError,( _L( "CUnderTaker::RunError" ) ) );
+
+ return aError;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: Completed
+
+ Description: Is request completed
+
+ Parameters: None
+
+ Return Values: TBool Completed?
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TBool CUnderTaker::Completed()
+ {
+
+ if( iStatus == KRequestPending )
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CUnderTaker
+
+ Method: SetSynchronousMode
+
+ Description: Set or unsets local processing mode
+
+ Parameters: const TBool aMode :in: Mode
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CUnderTaker::SetSynchronousMode( const TBool aMode )
+ {
+
+ iSynchronousMode = aMode;
+
+ }
+
+// End of File