--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omxil/xmltestharness/xmlclient/src/omxthreadrequest.cpp Fri May 07 16:25:23 2010 +0100
@@ -0,0 +1,255 @@
+/*
+* 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:
+*
+*/
+
+
+/**
+@file
+@internalComponent
+*/
+
+#include "omxthreadrequest.h"
+
+COmxThreadRequest* COmxThreadRequest::NewL()
+ {
+ COmxThreadRequest* self = new (ELeave) COmxThreadRequest();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+COmxThreadRequest::COmxThreadRequest()
+ {
+ }
+
+void COmxThreadRequest::ConstructL()
+ {
+ //Parameters to send to the sub thread
+ TThreadParam param;
+ param.iThreadRequestObj = this;
+
+ //Get a reference to this thread's heap
+ RHeap& thisHeap = User::Heap();
+
+ //Get the id of this thread
+ RThread thisThread;
+ TThreadId thisThreadId = thisThread.Id();
+ param.iMainThreadId = thisThreadId;
+
+ //Get a request to signal for setup completion
+ TRequestStatus setupComplete = KRequestPending;
+ param.iSetupComplete = &setupComplete;
+
+ //current time and the "this" pointer for a unique key
+ _LIT(KFormatString,"%S.%020Lu.%08X");
+ TName threadName;
+ TTime now;
+ now.UniversalTime();
+ threadName.Format(KFormatString, &KXMLClientOMXThreadName, now.Int64(), reinterpret_cast<TUint>(this));
+
+ //Create a new thread using the same heap as this thread
+ TInt result = iRequestThread.Create(threadName,
+ ThreadCreateFunction,
+ KDefaultStackSize,
+ &thisHeap,
+ ¶m);
+ User::LeaveIfError(result);
+
+ //Run the thread under high priority
+ iRequestThread.SetPriority(EPriorityNormal);
+
+ //Wait for thread startup to complete
+ TRequestStatus threadStatus = KRequestPending;
+ iRequestThread.Logon(threadStatus);
+
+ //Start the thread
+ iRequestThread.Resume();
+ User::WaitForRequest(threadStatus, setupComplete);
+ if(threadStatus != KRequestPending)
+ {
+ //Thread creation failed
+ TInt reason = iRequestThread.ExitReason();
+ User::Leave(reason);
+ }
+
+ // Thread creation was successfull
+ TInt error = iRequestThread.LogonCancel(threadStatus);
+ User::LeaveIfError(error); // There is no outstanding request
+ User::WaitForRequest(threadStatus); // Consume the signal
+
+ iThreadCreated = ETrue;
+ User::LeaveIfError(setupComplete.Int());
+ }
+
+/**
+Main thread entry point for the omx sub-thread.
+Create a cleanup stack for the thread and process the commands
+inside a trap for cleanup behaviour.
+@internalComponent
+
+@param aPtr Parameters to be used for creating the thread.
+@return The error code for thread termination.
+*/
+TInt COmxThreadRequest::ThreadCreateFunction(TAny* aPtr)
+ {
+ TInt error = KErrNone;
+
+ // Create a cleanup stack for the thread
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if (cleanupStack)
+ {
+ if(error == KErrNone)
+ {
+ TRAP(error, ThreadTrapFunctionL(aPtr));
+ }
+ }
+ else
+ {
+ error = KErrNoMemory;
+ }
+
+ delete cleanupStack;
+ return error;
+ }
+
+/**
+Function for thread execution. If the thread is successfully created signal
+the main thread that the thread creation was successfull. Then enter OMX
+request loop.
+
+@internalComponent
+
+@param aPtr A pointer to a TThreadParam object containing the startup parameters
+ for the thread.
+*/
+void COmxThreadRequest::ThreadTrapFunctionL(TAny* aPtr)
+ {
+ TThreadParam* param = static_cast<TThreadParam*>(aPtr);
+ COmxThreadRequest* iThreadRequestObj = param->iThreadRequestObj;
+
+ // tell main thread that setup is complete
+ RThread mainThread;
+ mainThread.Open(param->iMainThreadId);
+ mainThread.RequestComplete(param->iSetupComplete, KErrNone);
+ mainThread.Close();
+
+ // loop to execute OMX commands in own thread
+ while(iThreadRequestObj->iFunction != EOMXFunctionCodeTerminate)
+ {
+ iThreadRequestObj->iRequestThreadStatus = KRequestPending;
+
+ // block until client request is made
+ User::WaitForRequest(iThreadRequestObj->iRequestThreadStatus);
+ switch(iThreadRequestObj->iFunction)
+ {
+ case EOMXFunctionCodeGetHandle:
+ iThreadRequestObj->iErrorType = OMX_GetHandle(
+ iThreadRequestObj->ipHandle,
+ iThreadRequestObj->icComponentName,
+ iThreadRequestObj->ipAppData,
+ iThreadRequestObj->ipCallBacks);
+ break;
+
+ case EOMXFunctionCodeFreeHandle:
+ iThreadRequestObj->iErrorType = OMX_FreeHandle(
+ iThreadRequestObj->ihComponent);
+ break;
+
+ case EOMXFunctionCodeTerminate:
+ break;
+
+ default:
+ // should never be reached
+ User::Panic(_L("COmxThreadRequest"), KErrNotSupported);
+ }
+
+ // complete client request
+ TRequestStatus *status = iThreadRequestObj->iCallingStatus;
+ RThread callingThread;
+ callingThread.Open(iThreadRequestObj->iCallingThreadId);
+ callingThread.RequestComplete(status, KErrNone);
+ callingThread.Close();
+ }
+ }
+
+COmxThreadRequest::~COmxThreadRequest()
+ {
+ if(iThreadCreated)
+ {
+ TRequestStatus status;
+ // Logon to ensure thread has completely terminated, not just broken out of message handling loop.
+ // In particular this ensures the cleanup stack is destroyed before the heap marks are inspected.
+ iRequestThread.Logon(status);
+ Terminate();
+ User::WaitForRequest(status);
+ iThreadCreated = EFalse;
+ iRequestThread.Close();
+ }
+ }
+
+OMX_ERRORTYPE COmxThreadRequest::GetHandle(
+ OMX_OUT OMX_HANDLETYPE* pHandle,
+ OMX_IN OMX_STRING cComponentName,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_CALLBACKTYPE* pCallBacks)
+ {
+ ipHandle = pHandle;
+ icComponentName = cComponentName;
+ ipAppData = pAppData;
+ ipCallBacks = pCallBacks;
+
+ iFunction = EOMXFunctionCodeGetHandle;
+ DoRequest();
+
+ return iErrorType;
+ }
+
+OMX_ERRORTYPE COmxThreadRequest::FreeHandle(
+ OMX_IN OMX_HANDLETYPE hComponent)
+ {
+ ihComponent = hComponent;
+
+ iFunction = EOMXFunctionCodeFreeHandle;
+ DoRequest();
+
+ return iErrorType;
+ }
+
+void COmxThreadRequest::Terminate()
+ {
+ iFunction = EOMXFunctionCodeTerminate;
+ DoRequest();
+ }
+
+void COmxThreadRequest::DoRequest()
+ {
+ RThread me;
+ iCallingThreadId = me.Id();
+
+ TRequestStatus callingRequestStatus = KRequestPending;
+ iCallingStatus = &callingRequestStatus;
+
+ // send request to request thread
+ RThread requestThread;
+ requestThread.Open(iRequestThread.Id());
+ TRequestStatus* requestStatus = &iRequestThreadStatus;
+ requestThread.RequestComplete(requestStatus, KErrNone);
+ requestThread.Close();
+
+ // block calling request until OMX request completes
+ User::WaitForRequest(callingRequestStatus);
+ }