os/graphics/graphicscomposition/openwfcompositionengine/adaptation/src/Platform/OS/symbian/owfmessagequeue.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 //
     3 // Permission is hereby granted, free of charge, to any person obtaining a
     4 // copy of this software and/or associated documentation files (the
     5 // "Materials"), to deal in the Materials without restriction, including
     6 // without limitation the rights to use, copy, modify, merge, publish,
     7 // distribute, sublicense, and/or sell copies of the Materials, and to
     8 // permit persons to whom the Materials are furnished to do so, subject to
     9 // the following conditions:
    10 //
    11 // The above copyright notice and this permission notice shall be included
    12 // in all copies or substantial portions of the Materials.
    13 //
    14 // THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    20 // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
    21 //
    22 // Description:
    23 // 
    24 //
    25 //
    26 
    27 #define KInitialIndexValue (-1)
    28 
    29 #include "owfmessagequeue.h"
    30 #include "owfdebug.h"
    31 #include <e32base.h>
    32 
    33 class CMessageQueue: public CBase
    34     {
    35     public:
    36         virtual ~CMessageQueue();
    37         static CMessageQueue* NewL();
    38         static CMessageQueue* NewLC();
    39         void Send(TInt msg, void* data);
    40         TInt Fetch(OWF_MESSAGE* msg, TInt timeout);
    41         TInt Fetch(OWF_MESSAGE* msg);
    42         
    43     private:
    44         CMessageQueue();
    45         void ConstructL();
    46         
    47     private:
    48         const static TInt iQueueSize = 16;
    49         OWF_MESSAGE iMessageArray[iQueueSize];
    50         RSemaphore iFetchSeamaphore;
    51         RSemaphore iSendSemaphore;
    52         RFastLock iProtectionMutex;
    53         TInt iSendIndex;
    54         TInt iFetchIndex;
    55     };
    56 
    57 CMessageQueue::CMessageQueue():
    58 iSendIndex(KInitialIndexValue),
    59 iFetchIndex(KInitialIndexValue)
    60     {
    61     
    62     }
    63 
    64 CMessageQueue::~CMessageQueue()
    65     {
    66     iFetchSeamaphore.Close();
    67     iSendSemaphore.Close();
    68     iProtectionMutex.Close();
    69     }
    70 
    71 void CMessageQueue::ConstructL()
    72     {
    73     User::LeaveIfError(iFetchSeamaphore.CreateLocal(0));
    74     User::LeaveIfError(iSendSemaphore.CreateLocal(iQueueSize));
    75     User::LeaveIfError(iProtectionMutex.CreateLocal());
    76     }
    77 
    78 CMessageQueue* CMessageQueue::NewLC()
    79     {
    80     CMessageQueue* self = new(ELeave) CMessageQueue();
    81     CleanupStack::PushL(self);
    82     self->ConstructL();
    83     return(self);
    84     }
    85 
    86 CMessageQueue* CMessageQueue::NewL()
    87     {
    88     CMessageQueue* self = CMessageQueue::NewLC();
    89     CleanupStack::Pop(self);
    90     return self;
    91     }
    92 
    93 void CMessageQueue::Send(TInt msg, void* data)
    94     {
    95     iSendSemaphore.Wait();
    96     iProtectionMutex.Wait();
    97     iSendIndex = (iSendIndex + 1) % iQueueSize;
    98     iMessageArray[iSendIndex].id = msg;
    99     iMessageArray[iSendIndex].data = data;
   100     iProtectionMutex.Signal();
   101     iFetchSeamaphore.Signal();
   102     }
   103 
   104 TInt CMessageQueue::Fetch(OWF_MESSAGE* msg, TInt timeout)
   105     {
   106     TInt ret = KErrNone;
   107     if (!msg)
   108         {
   109         return KErrArgument;
   110         }
   111     
   112     if ((ret = iFetchSeamaphore.Wait(timeout)) == KErrNone)
   113         {
   114         iProtectionMutex.Wait();
   115         if (iSendIndex == iFetchIndex)
   116             {
   117             iProtectionMutex.Signal();
   118             return KErrTimedOut;
   119             }
   120         else
   121             {
   122             iFetchIndex = (iFetchIndex + 1) % iQueueSize;
   123             *msg = iMessageArray[iFetchIndex];
   124             iProtectionMutex.Signal();
   125             iSendSemaphore.Signal();
   126             return KErrNone;
   127             }
   128         }
   129     return ret;
   130     }
   131 
   132 TInt CMessageQueue::Fetch(OWF_MESSAGE* msg)
   133     {
   134     if (!msg)
   135         {
   136         return KErrArgument;
   137         }
   138     
   139     iFetchSeamaphore.Wait();
   140     iProtectionMutex.Wait();
   141     iFetchIndex = (iFetchIndex + 1) % iQueueSize;
   142     *msg = iMessageArray[iFetchIndex];
   143     iProtectionMutex.Signal();
   144     iSendSemaphore.Signal();
   145     return KErrNone;
   146     }
   147 
   148 OWF_API_CALL void
   149 OWF_MessageQueue_Destroy(OWF_MESSAGE_QUEUE* queue)
   150 {
   151     if (!queue) 
   152         {
   153         return;
   154         }
   155     delete (CMessageQueue*)queue->queuePtr;
   156     queue->queuePtr = NULL;
   157 }
   158 
   159 OWF_API_CALL OWFint
   160 OWF_MessageQueue_Init(OWF_MESSAGE_QUEUE* queue)
   161 {
   162     if (!queue) 
   163         {
   164         return MSG_QUEUE_INIT_ERR;
   165         }
   166     
   167     TRAPD(err, queue->queuePtr = CMessageQueue::NewL());
   168     return (err || !queue->queuePtr) ? MSG_QUEUE_INIT_ERR : MSG_QUEUE_INIT_OK;
   169 }
   170 
   171 OWF_API_CALL void
   172 OWF_Message_Send(OWF_MESSAGE_QUEUE* queue,
   173                  OWFuint msg,
   174                  void* data)
   175 {
   176     OWF_ASSERT(queue);
   177     OWF_ASSERT(queue->queuePtr);
   178     
   179     ((CMessageQueue*)(queue->queuePtr))->Send(msg, data);
   180 }
   181 
   182 OWF_API_CALL OWFint
   183 OWF_Message_Wait(OWF_MESSAGE_QUEUE* queue,
   184                  OWF_MESSAGE* msg,
   185                  OWFint timeout)
   186 {
   187     OWF_ASSERT(queue);
   188     OWF_ASSERT(queue->queuePtr);
   189     OWF_ASSERT(msg);
   190     
   191     OWFint ret = 0;
   192     
   193     if (WAIT_FOREVER == timeout)
   194         {
   195         ret = ((CMessageQueue*)(queue->queuePtr))->Fetch(msg);
   196         }
   197     else
   198         {
   199         ret = ((CMessageQueue*)(queue->queuePtr))->Fetch(msg, timeout);
   200         }
   201     switch (ret)
   202         {
   203         case KErrNone:
   204             return MSG_QUEUE_WAIT_MSG_FETCHED;
   205         case KErrTimedOut:
   206             return MSG_QUEUE_WAIT_MSG_TIMEDOUT;
   207         default:
   208             return MSG_QUEUE_WAIT_MSG_ERR;
   209         }
   210 }
   211