tsrc/xmltestharness/xmlclient/src/omxthreadrequest.cpp
changeset 0 0e4a32b9112d
equal deleted inserted replaced
-1:000000000000 0:0e4a32b9112d
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20 @file
       
    21 @internalComponent
       
    22 */
       
    23 
       
    24 #include "omxthreadrequest.h"
       
    25 
       
    26 COmxThreadRequest* COmxThreadRequest::NewL()
       
    27     {
       
    28     COmxThreadRequest* self = new (ELeave) COmxThreadRequest();
       
    29     CleanupStack::PushL(self);
       
    30     self->ConstructL();
       
    31     CleanupStack::Pop(self);
       
    32     return self;
       
    33     }
       
    34 
       
    35 COmxThreadRequest::COmxThreadRequest()
       
    36     {
       
    37     }
       
    38 
       
    39 void COmxThreadRequest::ConstructL()
       
    40     {
       
    41     //Parameters to send to the sub thread
       
    42     TThreadParam param;
       
    43     param.iThreadRequestObj = this;
       
    44     
       
    45     //Get a reference to this thread's heap
       
    46     RHeap& thisHeap = User::Heap();
       
    47             
       
    48     //Get the id of this thread
       
    49     RThread thisThread;
       
    50     TThreadId thisThreadId = thisThread.Id();
       
    51     param.iMainThreadId = thisThreadId;
       
    52     
       
    53     //Get a request to signal for setup completion
       
    54     TRequestStatus setupComplete = KRequestPending;
       
    55     param.iSetupComplete = &setupComplete;
       
    56     
       
    57     //current time and the "this" pointer for a unique key
       
    58     _LIT(KFormatString,"%S.%020Lu.%08X");
       
    59     TName threadName;
       
    60     TTime now;
       
    61     now.UniversalTime();
       
    62     threadName.Format(KFormatString, &KXMLClientOMXThreadName, now.Int64(), reinterpret_cast<TUint>(this));
       
    63 
       
    64     //Create a new thread using the same heap as this thread
       
    65     TInt result = iRequestThread.Create(threadName,
       
    66                                     ThreadCreateFunction,
       
    67                                     KDefaultStackSize,
       
    68                                     &thisHeap,
       
    69                                     &param);
       
    70     User::LeaveIfError(result);
       
    71 
       
    72     //Run the thread under high priority
       
    73     iRequestThread.SetPriority(EPriorityNormal); 
       
    74 
       
    75     //Wait for thread startup to complete
       
    76     TRequestStatus threadStatus = KRequestPending;
       
    77     iRequestThread.Logon(threadStatus);
       
    78 
       
    79     //Start the thread
       
    80     iRequestThread.Resume();
       
    81     User::WaitForRequest(threadStatus, setupComplete);
       
    82     if(threadStatus != KRequestPending)
       
    83         {
       
    84         //Thread creation failed
       
    85         TInt reason = iRequestThread.ExitReason();
       
    86         User::Leave(reason);
       
    87         }
       
    88 
       
    89     // Thread creation was successfull
       
    90     TInt error = iRequestThread.LogonCancel(threadStatus);
       
    91     User::LeaveIfError(error); // There is no outstanding request
       
    92     User::WaitForRequest(threadStatus); // Consume the signal
       
    93 
       
    94     iThreadCreated = ETrue;
       
    95     User::LeaveIfError(setupComplete.Int());
       
    96     }
       
    97 
       
    98 /**
       
    99 Main thread entry point for the omx sub-thread.
       
   100 Create a cleanup stack for the thread and process the commands
       
   101 inside a trap for cleanup behaviour.
       
   102 @internalComponent
       
   103 
       
   104 @param aPtr Parameters to be used for creating the thread.
       
   105 @return The error code for thread termination.
       
   106 */
       
   107 TInt COmxThreadRequest::ThreadCreateFunction(TAny* aPtr)
       
   108     {
       
   109     TInt error = KErrNone;
       
   110 
       
   111     // Create a cleanup stack for the thread
       
   112     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   113     if (cleanupStack)
       
   114         {
       
   115         if(error == KErrNone)
       
   116             {
       
   117             TRAP(error, ThreadTrapFunctionL(aPtr));
       
   118             }
       
   119         }
       
   120     else
       
   121         {
       
   122         error = KErrNoMemory;
       
   123         }
       
   124 
       
   125     delete cleanupStack;
       
   126     return error;
       
   127     }
       
   128 
       
   129 /**
       
   130 Function for thread execution. If the thread is successfully created signal
       
   131 the main thread that the thread creation was successfull. Then enter OMX
       
   132 request loop.
       
   133 
       
   134 @internalComponent
       
   135 
       
   136 @param aPtr A pointer to a TThreadParam object containing the startup parameters
       
   137             for the thread.
       
   138 */
       
   139 void COmxThreadRequest::ThreadTrapFunctionL(TAny* aPtr)
       
   140     {
       
   141     TThreadParam* param = static_cast<TThreadParam*>(aPtr);
       
   142     COmxThreadRequest* iThreadRequestObj = param->iThreadRequestObj;
       
   143     
       
   144     // tell main thread that setup is complete
       
   145     RThread mainThread;
       
   146     mainThread.Open(param->iMainThreadId);
       
   147     mainThread.RequestComplete(param->iSetupComplete, KErrNone);
       
   148     mainThread.Close();
       
   149     
       
   150     // loop to execute OMX commands in own thread
       
   151     while(iThreadRequestObj->iFunction != EOMXFunctionCodeTerminate)
       
   152         {
       
   153         iThreadRequestObj->iRequestThreadStatus = KRequestPending;
       
   154         
       
   155         // block until client request is made
       
   156         User::WaitForRequest(iThreadRequestObj->iRequestThreadStatus);
       
   157         switch(iThreadRequestObj->iFunction)
       
   158             {
       
   159             case EOMXFunctionCodeGetHandle:
       
   160                 iThreadRequestObj->iErrorType = OMX_GetHandle(
       
   161                         iThreadRequestObj->ipHandle,
       
   162                         iThreadRequestObj->icComponentName,
       
   163                         iThreadRequestObj->ipAppData,
       
   164                         iThreadRequestObj->ipCallBacks);
       
   165                 break;
       
   166                 
       
   167             case EOMXFunctionCodeFreeHandle:
       
   168                 iThreadRequestObj->iErrorType = OMX_FreeHandle(
       
   169                         iThreadRequestObj->ihComponent);
       
   170                 break;
       
   171                 
       
   172             case EOMXFunctionCodeTerminate:
       
   173                 break;
       
   174                 
       
   175             default:
       
   176                 // should never be reached
       
   177                 User::Panic(_L("COmxThreadRequest"), KErrNotSupported);
       
   178             }
       
   179         
       
   180         // complete client request
       
   181         TRequestStatus *status = iThreadRequestObj->iCallingStatus;
       
   182         RThread callingThread;
       
   183         callingThread.Open(iThreadRequestObj->iCallingThreadId);
       
   184         callingThread.RequestComplete(status, KErrNone);
       
   185         callingThread.Close();
       
   186         }
       
   187     }
       
   188 
       
   189 COmxThreadRequest::~COmxThreadRequest()
       
   190     {
       
   191     if(iThreadCreated)
       
   192         {
       
   193         TRequestStatus status;
       
   194         // Logon to ensure thread has completely terminated, not just broken out of message handling loop.
       
   195         // In particular this ensures the cleanup stack is destroyed before the heap marks are inspected.
       
   196         iRequestThread.Logon(status);
       
   197         Terminate();
       
   198         User::WaitForRequest(status);
       
   199         iThreadCreated = EFalse;
       
   200         iRequestThread.Close();
       
   201         }
       
   202     }
       
   203 
       
   204 OMX_ERRORTYPE COmxThreadRequest::GetHandle(
       
   205         OMX_OUT OMX_HANDLETYPE* pHandle,
       
   206         OMX_IN  OMX_STRING cComponentName,
       
   207         OMX_IN  OMX_PTR pAppData,
       
   208         OMX_IN  OMX_CALLBACKTYPE* pCallBacks)
       
   209     {
       
   210     ipHandle = pHandle;
       
   211     icComponentName = cComponentName;
       
   212     ipAppData = pAppData;
       
   213     ipCallBacks = pCallBacks;
       
   214     
       
   215     iFunction = EOMXFunctionCodeGetHandle; 
       
   216     DoRequest();
       
   217     
       
   218     return iErrorType;
       
   219     }
       
   220 
       
   221 OMX_ERRORTYPE COmxThreadRequest::FreeHandle(
       
   222     OMX_IN  OMX_HANDLETYPE hComponent)
       
   223     {
       
   224     ihComponent = hComponent;
       
   225     
       
   226     iFunction = EOMXFunctionCodeFreeHandle; 
       
   227     DoRequest();
       
   228     
       
   229     return iErrorType;
       
   230     }
       
   231 
       
   232 void COmxThreadRequest::Terminate()
       
   233     {
       
   234     iFunction = EOMXFunctionCodeTerminate; 
       
   235     DoRequest();
       
   236     }
       
   237 
       
   238 void COmxThreadRequest::DoRequest()
       
   239     {
       
   240     RThread me;
       
   241     iCallingThreadId = me.Id();
       
   242 
       
   243     TRequestStatus callingRequestStatus = KRequestPending;
       
   244     iCallingStatus = &callingRequestStatus;
       
   245       
       
   246     // send request to request thread
       
   247     RThread requestThread;
       
   248     requestThread.Open(iRequestThread.Id());
       
   249     TRequestStatus* requestStatus = &iRequestThreadStatus;
       
   250     requestThread.RequestComplete(requestStatus, KErrNone);
       
   251     requestThread.Close();
       
   252      
       
   253     // block calling request until OMX request completes
       
   254     User::WaitForRequest(callingRequestStatus);
       
   255     }