diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/plugins/openwfcrs/src/openwfcjobmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/plugins/openwfcrs/src/openwfcjobmanager.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,426 @@ +// Copyright (c) 1995-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: +// + +#include "openwfcjobmanager.h" +#include "openwfcwrapper.h" +#include "openwfcthreadmanager.h" +#include "openwfcpanics.h" +#include + +#include + +COpenWfcJobManger::TComposeRequestDetails::TComposeRequestDetails(): +iCommitRequest(NULL), +iCallingThread(KNullThreadId) + { + + } + +void COpenWfcJobManger::TComposeRequestDetails::Set(TRequestStatus* aCommitRequest, TThreadId aCallingThread) + { + iCommitRequest = aCommitRequest; + iCallingThread = aCallingThread; + } + +void COpenWfcJobManger::TComposeRequestDetails::Reset() + { + iCommitRequest = NULL; + iCallingThread = KNullThreadId; + } + +COpenWfcJobManger::Guard::Guard(RMutex& aLock): +iLock(aLock) + { + iLock.Wait(); + } + +COpenWfcJobManger::Guard::~Guard() + { + iLock.Signal(); + } + +COpenWfcJobManger::COpenWfcJobManger(COpenWfcWrapper& aOpenWfcWrapper, + WFCDevice aDevice, + WFCContext aContext, + TInt aManagerId): +iComposeDetailsPool(_FOFF(TComposeRequestDetails, iDlink)), +iComposeDetailsPoolIter(iComposeDetailsPool), +iComposeDetailsList(_FOFF(TComposeRequestDetails, iDlink)), +iComposeDetailsListIter(iComposeDetailsList), +iOpenWfcWrapper(aOpenWfcWrapper), +iDevice(aDevice), +iContext(aContext), +iCompositionPaused(ETrue), +iPausedComposePending(ETrue), +iThreadManager(NULL), +iManagerId(aManagerId), +iSync(EGL_NO_SYNC_KHR), +iEglDisplay(aOpenWfcWrapper.Display()), +iOutstandingJob(EOpenWfcInvalidJobId) + { + + } + +COpenWfcJobManger::~COpenWfcJobManger() + { + JQLOG(("** ENTER * COpenWfcJobManger::~COpenWfcJobManger()")); + iCommandLock.Wait(); + iJobLock.Wait(); + + CompleteComposeRequests(KErrNone); + + delete iThreadManager; + + + TComposeRequestDetails* pDetail = NULL; + iComposeDetailsListIter.SetToFirst(); + while ((pDetail = iComposeDetailsListIter++) != NULL) + { + pDetail->iDlink.Deque(); + delete pDetail; + } + + iComposeDetailsPoolIter.SetToFirst(); + while ((pDetail = iComposeDetailsPoolIter++) != NULL) + { + pDetail->iDlink.Deque(); + delete pDetail; + } + + eglDestroySyncKHR(iEglDisplay, iSync); + iJobLock.Signal(); + iCommandLock.Signal(); + iJobLock.Close(); + iCommandLock.Close(); + JQLOG(("** EXIT * COpenWfcJobManger::~COpenWfcJobManger()")); + } + +COpenWfcJobManger* COpenWfcJobManger::NewLC(COpenWfcWrapper& aOpenWfcWrapper, + WFCDevice aDevice, + WFCContext aContext, + TInt aManagerId) + { + COpenWfcJobManger* self = new(ELeave) COpenWfcJobManger(aOpenWfcWrapper, aDevice, aContext, aManagerId); + CleanupStack::PushL(self); + self->ConstructL(); + return(self); + } + +COpenWfcJobManger* COpenWfcJobManger::NewL(COpenWfcWrapper& aOpenWfcWrapper, + WFCDevice aDevice, + WFCContext aContext, + TInt aManagerId) + { + COpenWfcJobManger* self = COpenWfcJobManger::NewLC(aOpenWfcWrapper, aDevice, aContext, aManagerId); + CleanupStack::Pop(self); + return self; + } + +void COpenWfcJobManger::ConstructL() + { + User::LeaveIfError(iJobLock.CreateLocal()); + User::LeaveIfError(iCommandLock.CreateLocal()); + User::LeaveIfNull(iThreadManager = COpenWfcMonitorThread::NewL(iManagerId, *this)); + + TComposeRequestDetails* pDetail = NULL; + for (TInt i = 0; i < KComposeDetailsPoolSize; i++) + { + pDetail = new (ELeave) TComposeRequestDetails(); + iComposeDetailsPool.AddLast(*pDetail); + } + + EGLint attrib_list[1] = { EGL_NONE }; + + iSync = eglCreateSyncKHR(iEglDisplay, + EGL_SYNC_REUSABLE_KHR, + attrib_list); + + if (iSync == EGL_NO_SYNC_KHR) + { //code inspection reveals the only reason eglsync will fail is for memory... + User::Leave(KErrNoMemory); + } + } + + +COpenWfcJobManger::TComposeRequestDetails* COpenWfcJobManger::AppendDetailsFromPool() + { + iComposeDetailsPoolIter.SetToFirst(); + TComposeRequestDetails* pDetails = iComposeDetailsPoolIter; + if (pDetails) + { + pDetails->iDlink.Deque(); + iComposeDetailsList.AddLast(*pDetails); + } + return pDetails; + } + + +void COpenWfcJobManger::ComposeRequest(TRequestStatus* aCompleted) + { + JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) WAIT FOR LOCKS", aCompleted)); + Guard g(iCommandLock); + + JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) COMMAND LOCK ACQUIRED", aCompleted)); + { + Guard g(iJobLock); + JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) JOB LOCK ACQUIRED", aCompleted)); + if (iCompositionPaused) + { + JQLOG(("** COpenWfcJobManger::ComposeRequest() EOpenWfcComposeJobId TRIGER compose job when resumed")); + iPausedComposePending = ETrue; + } + else + { + // in this point we expect that the oustanding command is compose if any + JQLOG(("** COpenWfcJobManger::ComposeRequest() EOpenWfcComposeJobId AUTONOMUS compose job")); + OPENWFC_ASSERT_DEBUG(iOutstandingJob == EOpenWfcComposeJobId || iOutstandingJob == EOpenWfcInvalidJobId, + EPanicWfcThreadManagerCannotQueueJob); + iOutstandingJob = EOpenWfcComposeJobId; + } + + // if pJob is NULL it means we have to add a Compose job to the job queue + + TInt err = wfcGetError(iDevice); + if (err) + { + JQLOG(("** COpenWfcJobManger::ComposeRequest() : ENTER FlushSceneElementChanges Error(%d)", err)); + } + iOpenWfcWrapper.FlushSceneElementChanges(); + // cleaning, also the "dirt" + err = wfcGetError(iDevice); + if (err) + { + JQLOG(("** COpenWfcJobManger::ComposeRequest() : EXIT FlushSceneElementChanges Error(%d)", err)); + } + + if (aCompleted) + { + // Let's store whatever compose complete notifications we may have + TComposeRequestDetails* pDetails = AppendDetailsFromPool(); + + if (pDetails) + { + // set the details if we could find a detail + JQLOG(("** COpenWfcJobManger::ComposeRequest(): StoreReq(0x%x))", aCompleted)); + pDetails->Set(aCompleted, RThread().Id()); + *aCompleted = KRequestPending; + } + else + { + // signal that enough is enough + JQLOG(("** COpenWfcJobManger::ComposeRequest(): OverflowReq(0x%x))", aCompleted)); + RThread().RequestComplete(aCompleted, KErrOverflow); + } + } + + JQLOG(("** COpenWfcJobManger::ComposeRequest(0x%x) JOB LOCK RELEASED", aCompleted)); + } + + // if a job has been queued, trigger the composition (it can happen only in autonomous mode) + if (iOutstandingJob == EOpenWfcComposeJobId) + { + JQLOG(("** COpenWfcJobManger::ComposeRequest(): iThreadManager->Signal()")); + iThreadManager->Signal(); + } + + JQLOG(("** EXIT * COpenWfcJobManger::ComposeRequest()")); + } + +void COpenWfcJobManger::CompositionPauseRequest() + { + JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() WAIT FOR LOCKS")); + Guard g(iCommandLock); + JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() COMMAND LOCK ACQUIRED")); + TBool newJob = EFalse; + { + Guard g(iJobLock); + JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() JOB LOCK ACQUIRED")); + if (!iCompositionPaused) + { + iCompositionPaused = ETrue; + if (iOutstandingJob == EOpenWfcComposeJobId) + { + JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() found outstanding composition request")); + iPausedComposePending = ETrue; + } + + iOutstandingJob = EOpenWfcPauseCompositionJobId; + iPauseResumeRequestStatus = KRequestPending; + iPauseResumeThread = RThread().Id(); + newJob = ETrue; + JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() : trigger new job")); + } + JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() JOB LOCK RELEASED")); + } + + if(newJob) + { + JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() : Signal()")); + iThreadManager->Signal(); + User::WaitForRequest(iPauseResumeRequestStatus); + } + + JQLOG(("** EXIT * COpenWfcJobManger::CompositionPauseRequest()")); + } + +void COpenWfcJobManger::CompositionResumeRequest() + { + JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() WAIT FOR LOCK")); + Guard g(iCommandLock); + JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() COMMAND LOCK ACQUIRED")); + TBool newJob = EFalse; + { + Guard g(iJobLock); + JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() JOB LOCK ACQUIRED")); + if (iCompositionPaused) + { + iOutstandingJob = EOpenWfcResumeCompositionJobId; + iPauseResumeRequestStatus = KRequestPending; + iPauseResumeThread = RThread().Id(); + newJob = ETrue; + JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() : trigger new job")); + } + JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() JOB LOCK RELEASED")); + } + + if(newJob) + { + JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() : Signal")); + iThreadManager->Signal(); + User::WaitForRequest(iPauseResumeRequestStatus); + } + + JQLOG(("** EXIT * COpenWfcJobManger::CompositionResumeRequest()")); + } + +void COpenWfcJobManger::CompleteComposeRequests(TInt aResult) + { + TComposeRequestDetails* pDetail = NULL; + iComposeDetailsListIter.SetToFirst(); + + while ((pDetail = iComposeDetailsListIter++) != NULL) + { + RThread thread; + if (pDetail->iCommitRequest && (thread.Open(pDetail->iCallingThread) == KErrNone)) + { + JQLOG(("** COpenWfcJobManger::CompleteComposeRequests(): CompleteReq(0x%x) Result(%d))", pDetail->iCommitRequest, aResult)); + thread.RequestComplete(pDetail->iCommitRequest, aResult); + thread.Close(); + } + + pDetail->iDlink.Deque(); + iComposeDetailsPool.AddLast(*pDetail); + pDetail->Reset(); + } + } + +void COpenWfcJobManger::CompletePauseResumeRequest(TInt aResult) + { + RThread thread; + if (thread.Open(iPauseResumeThread) == KErrNone) + { + TRequestStatus* rs= &iPauseResumeRequestStatus; + JQLOG(("** COpenWfcJobManger::CompletePauseResumeRequest(): %d)", aResult)); + thread.RequestComplete(rs, aResult); + thread.Close(); + } + } + +void COpenWfcJobManger::DoExecuteJob() + { + JQLOG(("** ENTER * COpenWfcJobManger::DoExecuteJob() Enter Wait for Job Lock")); + iJobLock.Wait(); + JQLOG(("** COpenWfcJobManger::DoExecuteJob(%d)", iOutstandingJob)); + EOpenWfcJobId job = iOutstandingJob; + iOutstandingJob = EOpenWfcInvalidJobId; + switch (job) + { + case EOpenWfcComposeJobId: + DoComposeJob(); + break; + case EOpenWfcPauseCompositionJobId: + DoPauseCompositionJob(); + break; + case EOpenWfcResumeCompositionJobId: + DoResumeCompositionJob(); + break; + default: + iJobLock.Signal(); + break; + } + + JQLOG(("** ENTER * COpenWfcJobManger::DoExecuteJob() Exit")); + } + +void COpenWfcJobManger::DoComposeJob() + { + JQLOG(("** ENTER * COpenWfcJobManger::DoComposeJob()")); + Commit(); + + Fence(); + WaitForSync(); + + // complete all the notifications stored until this momment + CompleteComposeRequests(KErrNone); + JQLOG(("** COpenWfcJobManger::DoComposeJob() LOCK RELEASED")); + + iJobLock.Signal(); + JQLOG(("** EXIT * COpenWfcJobManger::DoComposeJob()")); + } + +void COpenWfcJobManger::DoPauseCompositionJob() + { + JQLOG(("** ENTER * COpenWfcJobManger::DoPauseCompositionJob()")); + Deactivate(); + Fence(); + WaitForSync(); + CompletePauseResumeRequest(KErrNone); + JQLOG(("** COpenWfcJobManger::DoPauseCompositionJob() RELEASE LOCK")); + + iJobLock.Signal(); + JQLOG(("** EXIT * COpenWfcJobManger::DoPauseCompositionJob() job lock released")); + } + +void COpenWfcJobManger::DoResumeCompositionJob() + { + JQLOG(("** ENTER * COpenWfcJobManger::DoResumeCompositionJob()")); + + iComposeDetailsListIter.SetToFirst(); + TComposeRequestDetails* pQueuedRequest = iComposeDetailsListIter; + + if (iPausedComposePending || pQueuedRequest) + { + JQLOG(("** COpenWfcJobManger::Commit()")); + Commit(); + } + + Activate(); + + Fence(); + WaitForSync(); + + if (iPausedComposePending || pQueuedRequest) + { + CompleteComposeRequests(KErrNone); + iPausedComposePending = EFalse; + } + + iCompositionPaused = EFalse; + CompletePauseResumeRequest(KErrNone); + JQLOG(("** COpenWfcJobManger::DoResumeCompositionJob() RELEASE LOCK")); + + iJobLock.Signal(); + JQLOG(("** EXIT * COpenWfcJobManger::DoResumeCompositionJob() job lock released")); + }