uiacceltk/hitchcock/plugins/openwfcrs/src/openwfcjobmanager.cpp
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "openwfcjobmanager.h"
       
    17 #include "openwfcwrapper.h"
       
    18 #include "openwfcthreadmanager.h"
       
    19 #include "openwfcpanics.h"
       
    20 #include <e32debug.h>
       
    21 
       
    22 #include <graphics/eglsynchelper.h>
       
    23 
       
    24 COpenWfcJobManger::TComposeRequestDetails::TComposeRequestDetails():
       
    25 iCommitRequest(NULL),
       
    26 iCallingThread(KNullThreadId)
       
    27     {
       
    28     
       
    29     }
       
    30 
       
    31 void COpenWfcJobManger::TComposeRequestDetails::Set(TRequestStatus* aCommitRequest, TThreadId aCallingThread)
       
    32     {
       
    33     iCommitRequest = aCommitRequest;
       
    34     iCallingThread = aCallingThread;
       
    35     }
       
    36 
       
    37 void COpenWfcJobManger::TComposeRequestDetails::Reset()
       
    38     {
       
    39     iCommitRequest = NULL;
       
    40     iCallingThread = KNullThreadId;
       
    41     }
       
    42 
       
    43 COpenWfcJobManger::Guard::Guard(RMutex& aLock):
       
    44 iLock(aLock)
       
    45     {
       
    46     iLock.Wait();
       
    47     }
       
    48 
       
    49 COpenWfcJobManger::Guard::~Guard()
       
    50     {
       
    51     iLock.Signal();
       
    52     }
       
    53 
       
    54 COpenWfcJobManger::COpenWfcJobManger(COpenWfcWrapper& aOpenWfcWrapper, 
       
    55                                            WFCDevice aDevice, 
       
    56                                            WFCContext aContext,
       
    57                                            TInt aManagerId):
       
    58 iComposeDetailsPool(_FOFF(TComposeRequestDetails, iDlink)),
       
    59 iComposeDetailsPoolIter(iComposeDetailsPool),
       
    60 iComposeDetailsList(_FOFF(TComposeRequestDetails, iDlink)),
       
    61 iComposeDetailsListIter(iComposeDetailsList),
       
    62 iOpenWfcWrapper(aOpenWfcWrapper),
       
    63 iDevice(aDevice),
       
    64 iContext(aContext),
       
    65 iCompositionPaused(ETrue),
       
    66 iPausedComposePending(ETrue),
       
    67 iThreadManager(NULL),
       
    68 iManagerId(aManagerId),
       
    69 iSync(EGL_NO_SYNC_KHR),
       
    70 iEglDisplay(aOpenWfcWrapper.Display()),
       
    71 iOutstandingJob(EOpenWfcInvalidJobId)
       
    72     {
       
    73     
       
    74     }
       
    75 
       
    76 COpenWfcJobManger::~COpenWfcJobManger()
       
    77     {
       
    78     JQLOG(("** ENTER * COpenWfcJobManger::~COpenWfcJobManger()"));
       
    79     iCommandLock.Wait();
       
    80     iJobLock.Wait();
       
    81     
       
    82     CompleteComposeRequests(KErrNone);
       
    83     
       
    84     delete iThreadManager;
       
    85 
       
    86     
       
    87     TComposeRequestDetails* pDetail = NULL;
       
    88     iComposeDetailsListIter.SetToFirst();
       
    89     while ((pDetail = iComposeDetailsListIter++) != NULL)
       
    90         {
       
    91         pDetail->iDlink.Deque();
       
    92         delete pDetail;
       
    93         }
       
    94 
       
    95     iComposeDetailsPoolIter.SetToFirst();
       
    96     while ((pDetail = iComposeDetailsPoolIter++) != NULL)
       
    97         {
       
    98         pDetail->iDlink.Deque();
       
    99         delete pDetail;
       
   100         }
       
   101     
       
   102     eglDestroySyncKHR(iEglDisplay, iSync);
       
   103     iJobLock.Signal();
       
   104     iCommandLock.Signal();
       
   105     iJobLock.Close();
       
   106     iCommandLock.Close();
       
   107     JQLOG(("** EXIT * COpenWfcJobManger::~COpenWfcJobManger()"));
       
   108     }
       
   109 
       
   110 COpenWfcJobManger* COpenWfcJobManger::NewLC(COpenWfcWrapper& aOpenWfcWrapper, 
       
   111                                                  WFCDevice aDevice, 
       
   112                                                  WFCContext aContext,
       
   113                                                  TInt aManagerId)
       
   114     {
       
   115     COpenWfcJobManger* self = new(ELeave) COpenWfcJobManger(aOpenWfcWrapper, aDevice, aContext, aManagerId);
       
   116     CleanupStack::PushL(self);
       
   117     self->ConstructL();
       
   118     return(self);
       
   119     }
       
   120 
       
   121 COpenWfcJobManger* COpenWfcJobManger::NewL(COpenWfcWrapper& aOpenWfcWrapper, 
       
   122                                                   WFCDevice aDevice, 
       
   123                                                   WFCContext aContext,
       
   124                                                   TInt aManagerId)
       
   125     {
       
   126     COpenWfcJobManger* self = COpenWfcJobManger::NewLC(aOpenWfcWrapper, aDevice, aContext, aManagerId);
       
   127     CleanupStack::Pop(self);
       
   128     return self;
       
   129     }
       
   130     
       
   131 void COpenWfcJobManger::ConstructL()
       
   132     {
       
   133     User::LeaveIfError(iJobLock.CreateLocal());
       
   134     User::LeaveIfError(iCommandLock.CreateLocal());
       
   135     User::LeaveIfNull(iThreadManager = COpenWfcMonitorThread::NewL(iManagerId, *this));
       
   136     
       
   137     TComposeRequestDetails* pDetail = NULL;
       
   138     for (TInt i = 0; i < KComposeDetailsPoolSize; i++)
       
   139         {
       
   140         pDetail = new (ELeave) TComposeRequestDetails();
       
   141         iComposeDetailsPool.AddLast(*pDetail);
       
   142         }
       
   143     
       
   144     EGLint attrib_list[1] = { EGL_NONE };
       
   145     
       
   146     iSync = eglCreateSyncKHR(iEglDisplay,
       
   147                              EGL_SYNC_REUSABLE_KHR,
       
   148                              attrib_list);
       
   149     
       
   150     if (iSync == EGL_NO_SYNC_KHR)
       
   151         {  //code inspection reveals the only reason eglsync will fail is for memory...
       
   152         User::Leave(KErrNoMemory);
       
   153         }
       
   154     }
       
   155 
       
   156 
       
   157 COpenWfcJobManger::TComposeRequestDetails* COpenWfcJobManger::AppendDetailsFromPool()
       
   158     {
       
   159     iComposeDetailsPoolIter.SetToFirst();
       
   160     TComposeRequestDetails* pDetails = iComposeDetailsPoolIter;
       
   161     if (pDetails)
       
   162         {
       
   163         pDetails->iDlink.Deque();
       
   164         iComposeDetailsList.AddLast(*pDetails);
       
   165         }
       
   166     return pDetails;
       
   167     }
       
   168 
       
   169 
       
   170 void COpenWfcJobManger::ComposeRequest(TRequestStatus* aCompleted)
       
   171     {
       
   172     JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) WAIT FOR LOCKS", aCompleted));
       
   173     Guard g(iCommandLock);
       
   174     
       
   175     JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) COMMAND LOCK ACQUIRED", aCompleted));
       
   176     {
       
   177     Guard g(iJobLock);
       
   178     JQLOG(("** ENTER * COpenWfcJobManger::ComposeRequest(0x%x) JOB LOCK ACQUIRED", aCompleted));
       
   179     if (iCompositionPaused)
       
   180         {
       
   181         JQLOG(("** COpenWfcJobManger::ComposeRequest() EOpenWfcComposeJobId TRIGER compose job when resumed"));
       
   182         iPausedComposePending = ETrue;
       
   183         }
       
   184     else
       
   185         {
       
   186         // in this point we expect that the oustanding command is compose if any
       
   187         JQLOG(("** COpenWfcJobManger::ComposeRequest() EOpenWfcComposeJobId AUTONOMUS compose job"));
       
   188         OPENWFC_ASSERT_DEBUG(iOutstandingJob == EOpenWfcComposeJobId || iOutstandingJob == EOpenWfcInvalidJobId, 
       
   189                             EPanicWfcThreadManagerCannotQueueJob);
       
   190         iOutstandingJob = EOpenWfcComposeJobId;
       
   191         }
       
   192         
       
   193     // if pJob is NULL it means we have to add a Compose job to the job queue
       
   194     
       
   195     TInt err = wfcGetError(iDevice);
       
   196     if (err)
       
   197         {
       
   198         JQLOG(("** COpenWfcJobManger::ComposeRequest() : ENTER FlushSceneElementChanges Error(%d)", err));
       
   199         }
       
   200     iOpenWfcWrapper.FlushSceneElementChanges();
       
   201     // cleaning, also the "dirt"
       
   202     err = wfcGetError(iDevice);
       
   203     if (err)
       
   204         {
       
   205         JQLOG(("** COpenWfcJobManger::ComposeRequest() : EXIT FlushSceneElementChanges Error(%d)", err));
       
   206         }
       
   207     
       
   208     if (aCompleted)
       
   209         {
       
   210         // Let's store whatever compose complete notifications we may have
       
   211         TComposeRequestDetails* pDetails = AppendDetailsFromPool();
       
   212         
       
   213         if (pDetails)
       
   214             {
       
   215             // set the details if we could find a detail
       
   216             JQLOG(("** COpenWfcJobManger::ComposeRequest(): StoreReq(0x%x))", aCompleted));
       
   217             pDetails->Set(aCompleted, RThread().Id());
       
   218             *aCompleted = KRequestPending;
       
   219             }
       
   220         else
       
   221             {
       
   222             // signal that enough is enough
       
   223             JQLOG(("** COpenWfcJobManger::ComposeRequest(): OverflowReq(0x%x))", aCompleted));
       
   224             RThread().RequestComplete(aCompleted, KErrOverflow);
       
   225             }
       
   226         }
       
   227     
       
   228     JQLOG(("** COpenWfcJobManger::ComposeRequest(0x%x) JOB LOCK RELEASED", aCompleted));
       
   229     }
       
   230     
       
   231     // if a job has been queued, trigger the composition (it can happen only in autonomous mode)
       
   232     if (iOutstandingJob == EOpenWfcComposeJobId)
       
   233         {
       
   234         JQLOG(("** COpenWfcJobManger::ComposeRequest(): iThreadManager->Signal()"));
       
   235         iThreadManager->Signal();
       
   236         }
       
   237     
       
   238     JQLOG(("** EXIT * COpenWfcJobManger::ComposeRequest()"));
       
   239     }
       
   240 
       
   241 void COpenWfcJobManger::CompositionPauseRequest()
       
   242     {
       
   243     JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() WAIT FOR LOCKS"));
       
   244     Guard g(iCommandLock);
       
   245     JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() COMMAND LOCK ACQUIRED"));
       
   246     TBool newJob = EFalse; 
       
   247         {
       
   248         Guard g(iJobLock);
       
   249         JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() JOB LOCK ACQUIRED"));
       
   250         if (!iCompositionPaused)
       
   251             {
       
   252             iCompositionPaused = ETrue;
       
   253             if (iOutstandingJob == EOpenWfcComposeJobId)
       
   254                 {
       
   255                 JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() found outstanding composition request"));
       
   256                 iPausedComposePending = ETrue;
       
   257                 }
       
   258         
       
   259             iOutstandingJob = EOpenWfcPauseCompositionJobId;
       
   260             iPauseResumeRequestStatus = KRequestPending;
       
   261             iPauseResumeThread = RThread().Id();
       
   262             newJob = ETrue;
       
   263             JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() : trigger new job"));
       
   264             }
       
   265         JQLOG(("** ENTER * COpenWfcJobManger::CompositionPauseRequest() JOB LOCK RELEASED"));
       
   266         }
       
   267     
       
   268     if(newJob)
       
   269         {
       
   270         JQLOG(("** COpenWfcJobManger::CompositionPauseRequest() : Signal()"));
       
   271         iThreadManager->Signal();
       
   272         User::WaitForRequest(iPauseResumeRequestStatus);
       
   273         }
       
   274     
       
   275     JQLOG(("** EXIT * COpenWfcJobManger::CompositionPauseRequest()"));
       
   276     }
       
   277 
       
   278 void COpenWfcJobManger::CompositionResumeRequest()
       
   279     {
       
   280     JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() WAIT FOR LOCK"));
       
   281     Guard g(iCommandLock);
       
   282     JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() COMMAND LOCK ACQUIRED"));
       
   283     TBool newJob = EFalse;
       
   284         {
       
   285         Guard g(iJobLock);
       
   286         JQLOG(("** ENTER * COpenWfcJobManger::CompositionResumeRequest() JOB LOCK ACQUIRED"));
       
   287         if (iCompositionPaused)
       
   288             {
       
   289             iOutstandingJob = EOpenWfcResumeCompositionJobId;
       
   290             iPauseResumeRequestStatus = KRequestPending;
       
   291             iPauseResumeThread = RThread().Id();
       
   292             newJob = ETrue;
       
   293             JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() : trigger new job"));
       
   294             }
       
   295         JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() JOB LOCK RELEASED"));
       
   296         }
       
   297         
       
   298     if(newJob)
       
   299         {
       
   300         JQLOG(("** COpenWfcJobManger::CompositionResumeRequest() : Signal"));
       
   301         iThreadManager->Signal();
       
   302         User::WaitForRequest(iPauseResumeRequestStatus);
       
   303         }
       
   304     
       
   305     JQLOG(("** EXIT * COpenWfcJobManger::CompositionResumeRequest()"));
       
   306     }
       
   307 
       
   308 void COpenWfcJobManger::CompleteComposeRequests(TInt aResult)
       
   309     {
       
   310     TComposeRequestDetails* pDetail = NULL;
       
   311     iComposeDetailsListIter.SetToFirst();
       
   312     
       
   313     while ((pDetail = iComposeDetailsListIter++) != NULL)
       
   314         {
       
   315         RThread thread;
       
   316         if (pDetail->iCommitRequest && (thread.Open(pDetail->iCallingThread) == KErrNone))
       
   317             {
       
   318             JQLOG(("** COpenWfcJobManger::CompleteComposeRequests(): CompleteReq(0x%x) Result(%d))", pDetail->iCommitRequest, aResult));
       
   319             thread.RequestComplete(pDetail->iCommitRequest, aResult);
       
   320             thread.Close();
       
   321             }
       
   322         
       
   323         pDetail->iDlink.Deque();
       
   324         iComposeDetailsPool.AddLast(*pDetail);
       
   325         pDetail->Reset();
       
   326         }
       
   327     }
       
   328 
       
   329 void COpenWfcJobManger::CompletePauseResumeRequest(TInt aResult)
       
   330     {
       
   331     RThread thread;
       
   332     if (thread.Open(iPauseResumeThread) == KErrNone)
       
   333         {
       
   334         TRequestStatus* rs= &iPauseResumeRequestStatus;
       
   335         JQLOG(("** COpenWfcJobManger::CompletePauseResumeRequest(): %d)", aResult));
       
   336         thread.RequestComplete(rs, aResult);
       
   337         thread.Close();
       
   338         }
       
   339     }
       
   340 
       
   341 void COpenWfcJobManger::DoExecuteJob()
       
   342     {
       
   343     JQLOG(("** ENTER * COpenWfcJobManger::DoExecuteJob() Enter Wait for Job Lock"));
       
   344     iJobLock.Wait();
       
   345     JQLOG(("** COpenWfcJobManger::DoExecuteJob(%d)", iOutstandingJob));
       
   346     EOpenWfcJobId job = iOutstandingJob;
       
   347     iOutstandingJob = EOpenWfcInvalidJobId;
       
   348     switch (job)
       
   349         {
       
   350         case EOpenWfcComposeJobId:
       
   351             DoComposeJob();
       
   352             break;
       
   353         case EOpenWfcPauseCompositionJobId:
       
   354             DoPauseCompositionJob();
       
   355             break;
       
   356         case EOpenWfcResumeCompositionJobId:
       
   357             DoResumeCompositionJob();
       
   358             break;
       
   359         default:
       
   360             iJobLock.Signal();
       
   361             break;
       
   362         }
       
   363     
       
   364     JQLOG(("** ENTER * COpenWfcJobManger::DoExecuteJob() Exit"));
       
   365     }
       
   366 
       
   367 void COpenWfcJobManger::DoComposeJob()
       
   368     {
       
   369     JQLOG(("** ENTER * COpenWfcJobManger::DoComposeJob()"));
       
   370     Commit();
       
   371     
       
   372     Fence();
       
   373     WaitForSync();
       
   374     
       
   375     // complete all the notifications stored until this momment
       
   376     CompleteComposeRequests(KErrNone);
       
   377     JQLOG(("** COpenWfcJobManger::DoComposeJob() LOCK RELEASED"));
       
   378     
       
   379     iJobLock.Signal();
       
   380     JQLOG(("** EXIT * COpenWfcJobManger::DoComposeJob()"));
       
   381     }
       
   382 
       
   383 void COpenWfcJobManger::DoPauseCompositionJob()
       
   384     {
       
   385     JQLOG(("** ENTER * COpenWfcJobManger::DoPauseCompositionJob()"));
       
   386     Deactivate();
       
   387     Fence();
       
   388     WaitForSync();
       
   389     CompletePauseResumeRequest(KErrNone);
       
   390     JQLOG(("** COpenWfcJobManger::DoPauseCompositionJob() RELEASE LOCK"));
       
   391     
       
   392     iJobLock.Signal();
       
   393     JQLOG(("** EXIT * COpenWfcJobManger::DoPauseCompositionJob() job lock released"));
       
   394     }
       
   395 
       
   396 void COpenWfcJobManger::DoResumeCompositionJob()
       
   397     {
       
   398     JQLOG(("** ENTER * COpenWfcJobManger::DoResumeCompositionJob()"));
       
   399     
       
   400     iComposeDetailsListIter.SetToFirst();
       
   401     TComposeRequestDetails* pQueuedRequest = iComposeDetailsListIter;
       
   402     
       
   403     if (iPausedComposePending || pQueuedRequest)
       
   404         {
       
   405         JQLOG(("** COpenWfcJobManger::Commit()"));
       
   406         Commit();
       
   407         }
       
   408     
       
   409     Activate();
       
   410     
       
   411     Fence();
       
   412     WaitForSync();
       
   413     
       
   414     if (iPausedComposePending || pQueuedRequest)
       
   415         {
       
   416         CompleteComposeRequests(KErrNone);
       
   417         iPausedComposePending = EFalse;
       
   418         }
       
   419     
       
   420     iCompositionPaused = EFalse;
       
   421     CompletePauseResumeRequest(KErrNone);
       
   422     JQLOG(("** COpenWfcJobManger::DoResumeCompositionJob() RELEASE LOCK"));
       
   423     
       
   424     iJobLock.Signal();
       
   425     JQLOG(("** EXIT * COpenWfcJobManger::DoResumeCompositionJob() job lock released"));
       
   426     }