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