searcher/tsrc/robustnesstest/src/cworker.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 02 Sep 2010 21:37:32 +0300
changeset 18 3e1f76dd2722
parent 0 671dee74050a
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2010 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: 
*
*/

#include "CWorker.h"

#include "robustnesstest.pan"

#include <e32math.h>

TInt LogRand( TInt aDeviation ) 
	{
	TInt rv = 0; 
	while ( Math::Random() % aDeviation ) rv++;
	return rv; 
	}

void SleepRandom( TInt aAverageMs ) 
	{
	TInt sleepMs = LogRand( 10 ) * aAverageMs / 10; 
	User::After( sleepMs * 1000 );
	}

CWorker::CWorker() 
	: iWorkerId( iNextFreeWorkerId++ ),
	  iError( KErrNone ),
	  iExitTime(),
      iReported(),
      iActive( EFalse ),
	  iThread(), 
	  iSemaphore(),
	  iLock()
	  	{
		}

void CWorker::ConstructL() 
	{
	User::LeaveIfError( iSemaphore.CreateLocal( 0 ) ); 
	User::LeaveIfError( iLock.CreateLocal( 1 ) ); 
	}

CWorker::~CWorker() 
	{
	if ( iActive ) 
		{
		Cancel(); 
		while ( TryJoin(1000) != KErrNone ){}

		}
	iSemaphore.Close(); 
	iLock.Close(); 
	}

TInt CWorker::WorkerId() 
	{
	return iWorkerId; 
	}

TInt CWorker::Error() 
	{
	return iError; 
	}

const TTime& CWorker::ExitTime()
	{
	return iExitTime; 
	}

TBool CWorker::IsReported() 
	{
	return iReported; 
	}

void CWorker::SetReported() 
	{
	iReported = ETrue; 
	}

TBool CWorker::IsActive() 
	{
	return iActive; 
	}

void CWorker::StartL() 
	{
	iError = KErrNone;
	iReported = EFalse; 
	
	TThreadFunction function = CWorker::ThreadFunction; 
	
	User::LeaveIfError( iThread.Create( Name(), function, 2048, 0, this ) ); 
	 
	iActive = ETrue;
	iThread.Resume(); 
	// Go thread go
	
}

void CWorker::Cancel() 
	{
	DoCancel(); 
	}

TInt CWorker::TryJoin( TInt aMicroSeconds ) 
	{
	TInt err = iSemaphore.Wait( aMicroSeconds );
	if ( err == KErrNone ) 
		{
		iActive = EFalse;
		iThread.Close();
		}
	return err;
	}

void CWorker::Terminate() 
	{
	iActive = EFalse;
	iThread.Panic( KRobustnessTestPanicCategory, KRobustnessTestTerminate ); 
	iThread.Close();
	}

void CWorker::Wait( TReal aSeconds ) 
	{
	RTimer timer; 
	TRequestStatus timerStatus; 
	timer.CreateLocal();        
	CleanupClosePushL( timer ); 
	
	timer.After( timerStatus, aSeconds * 1000 * 1000 ); 
	User::WaitForRequest(timerStatus); 
	
	CleanupStack::PopAndDestroy(); // timer 
	}

void CWorker::Lock() {
	iLock.Wait(); 
}

TInt CWorker::TryLock( TInt aMicroSeconds ) {
	return iLock.Wait( aMicroSeconds ); 
}

void CWorker::Unlock() {
	iLock.Signal(); 
}

void CWorker::RunL() 
	{
	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
	CleanupStack::PushL(scheduler);
	CActiveScheduler::Install(scheduler);
	
	Lock(); 
	TRAP(iError, DoRunL()); 
	iExitTime.HomeTime(); 
	Unlock(); 
	
	iSemaphore.Signal(); 
	
	CleanupStack::PopAndDestroy(scheduler);
	}

TInt CWorker::ThreadFunction(void *aThis) 
	{
	CTrapCleanup* cleanup = CTrapCleanup::New();

	TRAP_IGNORE
		( 
		(reinterpret_cast<CWorker*>(aThis))->RunL();
		); 

	delete cleanup;
	return KErrNone;
	}

TInt CWorker::iNextFreeWorkerId = 0;