os/graphics/graphicscomposition/openwfcompositionengine/adaptation/src/Platform/OS/symbian/owfmessagequeue.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfcompositionengine/adaptation/src/Platform/OS/symbian/owfmessagequeue.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,211 @@
1.4 +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +//
1.6 +// Permission is hereby granted, free of charge, to any person obtaining a
1.7 +// copy of this software and/or associated documentation files (the
1.8 +// "Materials"), to deal in the Materials without restriction, including
1.9 +// without limitation the rights to use, copy, modify, merge, publish,
1.10 +// distribute, sublicense, and/or sell copies of the Materials, and to
1.11 +// permit persons to whom the Materials are furnished to do so, subject to
1.12 +// the following conditions:
1.13 +//
1.14 +// The above copyright notice and this permission notice shall be included
1.15 +// in all copies or substantial portions of the Materials.
1.16 +//
1.17 +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1.18 +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1.19 +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1.20 +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1.21 +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1.22 +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1.23 +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
1.24 +//
1.25 +// Description:
1.26 +//
1.27 +//
1.28 +//
1.29 +
1.30 +#define KInitialIndexValue (-1)
1.31 +
1.32 +#include "owfmessagequeue.h"
1.33 +#include "owfdebug.h"
1.34 +#include <e32base.h>
1.35 +
1.36 +class CMessageQueue: public CBase
1.37 + {
1.38 + public:
1.39 + virtual ~CMessageQueue();
1.40 + static CMessageQueue* NewL();
1.41 + static CMessageQueue* NewLC();
1.42 + void Send(TInt msg, void* data);
1.43 + TInt Fetch(OWF_MESSAGE* msg, TInt timeout);
1.44 + TInt Fetch(OWF_MESSAGE* msg);
1.45 +
1.46 + private:
1.47 + CMessageQueue();
1.48 + void ConstructL();
1.49 +
1.50 + private:
1.51 + const static TInt iQueueSize = 16;
1.52 + OWF_MESSAGE iMessageArray[iQueueSize];
1.53 + RSemaphore iFetchSeamaphore;
1.54 + RSemaphore iSendSemaphore;
1.55 + RFastLock iProtectionMutex;
1.56 + TInt iSendIndex;
1.57 + TInt iFetchIndex;
1.58 + };
1.59 +
1.60 +CMessageQueue::CMessageQueue():
1.61 +iSendIndex(KInitialIndexValue),
1.62 +iFetchIndex(KInitialIndexValue)
1.63 + {
1.64 +
1.65 + }
1.66 +
1.67 +CMessageQueue::~CMessageQueue()
1.68 + {
1.69 + iFetchSeamaphore.Close();
1.70 + iSendSemaphore.Close();
1.71 + iProtectionMutex.Close();
1.72 + }
1.73 +
1.74 +void CMessageQueue::ConstructL()
1.75 + {
1.76 + User::LeaveIfError(iFetchSeamaphore.CreateLocal(0));
1.77 + User::LeaveIfError(iSendSemaphore.CreateLocal(iQueueSize));
1.78 + User::LeaveIfError(iProtectionMutex.CreateLocal());
1.79 + }
1.80 +
1.81 +CMessageQueue* CMessageQueue::NewLC()
1.82 + {
1.83 + CMessageQueue* self = new(ELeave) CMessageQueue();
1.84 + CleanupStack::PushL(self);
1.85 + self->ConstructL();
1.86 + return(self);
1.87 + }
1.88 +
1.89 +CMessageQueue* CMessageQueue::NewL()
1.90 + {
1.91 + CMessageQueue* self = CMessageQueue::NewLC();
1.92 + CleanupStack::Pop(self);
1.93 + return self;
1.94 + }
1.95 +
1.96 +void CMessageQueue::Send(TInt msg, void* data)
1.97 + {
1.98 + iSendSemaphore.Wait();
1.99 + iProtectionMutex.Wait();
1.100 + iSendIndex = (iSendIndex + 1) % iQueueSize;
1.101 + iMessageArray[iSendIndex].id = msg;
1.102 + iMessageArray[iSendIndex].data = data;
1.103 + iProtectionMutex.Signal();
1.104 + iFetchSeamaphore.Signal();
1.105 + }
1.106 +
1.107 +TInt CMessageQueue::Fetch(OWF_MESSAGE* msg, TInt timeout)
1.108 + {
1.109 + TInt ret = KErrNone;
1.110 + if (!msg)
1.111 + {
1.112 + return KErrArgument;
1.113 + }
1.114 +
1.115 + if ((ret = iFetchSeamaphore.Wait(timeout)) == KErrNone)
1.116 + {
1.117 + iProtectionMutex.Wait();
1.118 + if (iSendIndex == iFetchIndex)
1.119 + {
1.120 + iProtectionMutex.Signal();
1.121 + return KErrTimedOut;
1.122 + }
1.123 + else
1.124 + {
1.125 + iFetchIndex = (iFetchIndex + 1) % iQueueSize;
1.126 + *msg = iMessageArray[iFetchIndex];
1.127 + iProtectionMutex.Signal();
1.128 + iSendSemaphore.Signal();
1.129 + return KErrNone;
1.130 + }
1.131 + }
1.132 + return ret;
1.133 + }
1.134 +
1.135 +TInt CMessageQueue::Fetch(OWF_MESSAGE* msg)
1.136 + {
1.137 + if (!msg)
1.138 + {
1.139 + return KErrArgument;
1.140 + }
1.141 +
1.142 + iFetchSeamaphore.Wait();
1.143 + iProtectionMutex.Wait();
1.144 + iFetchIndex = (iFetchIndex + 1) % iQueueSize;
1.145 + *msg = iMessageArray[iFetchIndex];
1.146 + iProtectionMutex.Signal();
1.147 + iSendSemaphore.Signal();
1.148 + return KErrNone;
1.149 + }
1.150 +
1.151 +OWF_API_CALL void
1.152 +OWF_MessageQueue_Destroy(OWF_MESSAGE_QUEUE* queue)
1.153 +{
1.154 + if (!queue)
1.155 + {
1.156 + return;
1.157 + }
1.158 + delete (CMessageQueue*)queue->queuePtr;
1.159 + queue->queuePtr = NULL;
1.160 +}
1.161 +
1.162 +OWF_API_CALL OWFint
1.163 +OWF_MessageQueue_Init(OWF_MESSAGE_QUEUE* queue)
1.164 +{
1.165 + if (!queue)
1.166 + {
1.167 + return MSG_QUEUE_INIT_ERR;
1.168 + }
1.169 +
1.170 + TRAPD(err, queue->queuePtr = CMessageQueue::NewL());
1.171 + return (err || !queue->queuePtr) ? MSG_QUEUE_INIT_ERR : MSG_QUEUE_INIT_OK;
1.172 +}
1.173 +
1.174 +OWF_API_CALL void
1.175 +OWF_Message_Send(OWF_MESSAGE_QUEUE* queue,
1.176 + OWFuint msg,
1.177 + void* data)
1.178 +{
1.179 + OWF_ASSERT(queue);
1.180 + OWF_ASSERT(queue->queuePtr);
1.181 +
1.182 + ((CMessageQueue*)(queue->queuePtr))->Send(msg, data);
1.183 +}
1.184 +
1.185 +OWF_API_CALL OWFint
1.186 +OWF_Message_Wait(OWF_MESSAGE_QUEUE* queue,
1.187 + OWF_MESSAGE* msg,
1.188 + OWFint timeout)
1.189 +{
1.190 + OWF_ASSERT(queue);
1.191 + OWF_ASSERT(queue->queuePtr);
1.192 + OWF_ASSERT(msg);
1.193 +
1.194 + OWFint ret = 0;
1.195 +
1.196 + if (WAIT_FOREVER == timeout)
1.197 + {
1.198 + ret = ((CMessageQueue*)(queue->queuePtr))->Fetch(msg);
1.199 + }
1.200 + else
1.201 + {
1.202 + ret = ((CMessageQueue*)(queue->queuePtr))->Fetch(msg, timeout);
1.203 + }
1.204 + switch (ret)
1.205 + {
1.206 + case KErrNone:
1.207 + return MSG_QUEUE_WAIT_MSG_FETCHED;
1.208 + case KErrTimedOut:
1.209 + return MSG_QUEUE_WAIT_MSG_TIMEDOUT;
1.210 + default:
1.211 + return MSG_QUEUE_WAIT_MSG_ERR;
1.212 + }
1.213 +}
1.214 +