diff -r a151135b0cf9 -r aa2539c91954 debugsrv/runmodedebug/tsrc/rm_debug/common/t_target_launcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debugsrv/runmodedebug/tsrc/rm_debug/common/t_target_launcher.cpp Fri Oct 08 14:56:39 2010 +0300 @@ -0,0 +1,224 @@ +// Copyright (c) 2007-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: +// Helper app to launch debug targets. Uses command-line parameters as follows using a + sign: +// +n +// +m +// +o +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "t_target_launcher.h" + + +/** + Launch a process + + @param aProcess The RProcess object to use to create the process + @param aExeName File name of the executable to create the process from + @param aCommandLine The command line to pass to the new process + @return KErrNone on success, or one of the other system wide error codes + */ +TInt LaunchProcess(RProcess& aProcess, TDesC & aExeName, TPtr & aCommandLine ) + { + + TPtrC commandLine( aCommandLine ); + + TInt err = aProcess.Create( aExeName, commandLine ); + + // check that there was no error raised + if(err != KErrNone) + { + return err; + } + + TRequestStatus status = KRequestPending; + aProcess.Rendezvous(status); + + if(KRequestPending != status.Int()) + { + // startup failed so kill the process + RDebug::Printf( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() ); + aProcess.Kill(KErrNone); + return status.Int(); + } + else + { + // start up succeeded so resume the process + aProcess.Resume(); + User::WaitForRequest(status); + if(KErrNone != status.Int()) + { + RDebug::Printf( "> RProcess Resume() failed with %d. Killing process", status.Int() ); + aProcess.Kill(KErrNone); + } + return status.Int(); + } + } + +/** + * Read command line parameters and control the launching of targets. + * Create global launch semaphore KLaunchSemaphoreName + */ +void MainL() + { + + TInt numApps = KNumApps; + TInt numLaunches = KNumLaunches; + TInt launchControl = 0; + + TInt argc = User::CommandLineLength(); + HBufC* commandLine = NULL; + RDebug::Printf( ">Launcher Process() argc=%d", argc ); + + if( argc ) + { + commandLine = HBufC::NewLC(argc); + TPtr commandLineBuffer = commandLine->Des(); + User::CommandLine(commandLineBuffer); + + RBuf printCommandLine; + CleanupClosePushL( printCommandLine ); + printCommandLine.CreateL( commandLine->Des().Length() ); + printCommandLine.Copy( commandLine->Des() ); + printCommandLine.Collapse(); + RDebug::Printf( ">command line = %S", &printCommandLine ); + CleanupStack::PopAndDestroy( &printCommandLine ); + + // create a lexer and read through the command line + TLex lex(*commandLine); + while (!lex.Eos()) + { + // only look for options with first character '+', other switches are for the targets + if (lex.Get() == '+') + { + TChar arg = lex.Get(); + switch (arg) + { + case 'n': + lex.Val( numApps ); + RDebug::Printf("parsed numApps as %d", numApps); + break; + case 'm': + lex.Val( numLaunches ); + RDebug::Printf("parsed numLaunches as %d", numLaunches ); + break; + case 'o': + lex.Val( launchControl ); + RDebug::Printf("parsed launchControl as %d", launchControl); + break; + default: + // unknown argument ignore it + break; + }//switch + }// if + + }//while + }//if argc + + RSemaphore launchSemaphore; + TInt ret = KErrNone; + CleanupClosePushL( launchSemaphore ); + ret = launchSemaphore.CreateGlobal( KLaunchSemaphoreName, 0 ); + RDebug::Printf( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret); + User::LeaveIfError( ret ); + + ret = launchSemaphore.OpenGlobal( KLaunchSemaphoreName ); + RDebug::Printf( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret); + User::LeaveIfError( ret ); + + //Only now indicate to the launcher that we have fully started, so they can find and open the semaphore + RProcess::Rendezvous(KErrNone); + + //Now launch the requested number of apps for the requested number of launches + for( ; numLaunches > 0; numLaunches-- ) + { + for( TInt launchIndex = numApps; launchIndex > 0; launchIndex-- ) + { + RDebug::Printf( ">Target Launcher: Semaphore wait app %d, launch %d", launchIndex, numLaunches ); + launchSemaphore.Wait(); + + RBuf targetName; + CleanupClosePushL( targetName ); + RDebug::Printf( ">Target Launcher: targetName.Create %d, launch %d", launchIndex, numLaunches ); + targetName.Create( KTargetExe().Length() + 2 ); + + if( launchControl == 1 ) + { + // Reverse the order of the apps launched by reversing the index in the name + RDebug::Printf( ">Target Launcher: targetName.Format %d, launch %d", numApps - launchIndex + 1, numLaunches ); + targetName.Format( KTargetExe(), numApps - launchIndex + 1 ); + } + else + { + RDebug::Printf( ">Target Launcher: targetName.Format %d, launch %d", launchIndex, numLaunches ); + targetName.Format( KTargetExe(), launchIndex ); + } + + RProcess aProc; + CleanupClosePushL( aProc ); + + RDebug::Printf( ">Target Launcher: LaunchProcess %d, launch %d", launchIndex, numLaunches ); + RDebug::Printf( ">LaunchProcess %lS", &targetName ); + TPtr cmdLinePtr( commandLine->Des() ); + ret = LaunchProcess( aProc, targetName, cmdLinePtr ); + CleanupStack::PopAndDestroy( &aProc ); + + RDebug::Printf( "Launcher Process()" ); + + CTrapCleanup* trap = CTrapCleanup::New(); + if (!trap) + return KErrNoMemory; + + TRAPD(err, MainL()); + RDebug::Printf( "< Target launching returned %d", err); + + delete trap; + + return err; + }