mpx/commonframework/common/src/mpxmessagequeue.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpx/commonframework/common/src/mpxmessagequeue.cpp	Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,305 @@
+/*
+* Copyright (c) 2007 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:  Queue the message
+*
+*/
+
+#include <mpxlog.h>
+#ifdef _DEBUG
+#include <mpxmessagegeneraldefs.h>
+#endif
+#include "mpxmessagequeue.h"
+
+// ============================ PRIVATE CLASSES ==============================
+NONSHARABLE_CLASS(CMPXMessageItem) : public CBase
+    {
+public:
+    static CMPXMessageItem* NewL(const CMPXMessage* aMsg, TInt aError);
+    ~CMPXMessageItem();
+    /**
+     *  message object
+     *
+     *  @return message object
+     */
+    CMPXMessage* Message()
+        {
+        return iMsg;
+        }
+    /**
+     *  Error code associated with the message
+     *
+     *  @return the error code
+     */
+    TInt Error()
+        {
+        return iError;
+        }
+    /**
+     *  Offset to the task queue
+     *
+     *  @return the offset
+     */
+     static TInt Offset()
+         {
+         return _FOFF(CMPXMessageItem,iLink);
+         }
+private:
+    CMPXMessageItem(TInt aError);
+    void ConstructL(const CMPXMessage* aMsg);
+private:
+    TSglQueLink iLink;
+    CMPXMessage* iMsg;
+    TInt iError;
+    };
+
+CMPXMessageItem* CMPXMessageItem::NewL(const CMPXMessage* aMsg, TInt aError)
+    {
+    CMPXMessageItem* self = new ( ELeave ) CMPXMessageItem(aError);
+    CleanupStack::PushL( self );
+    self->ConstructL(aMsg);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CMPXMessageItem::CMPXMessageItem(TInt aError)
+:   iError(aError)
+    {
+    }
+
+CMPXMessageItem::~CMPXMessageItem()
+    {
+    MPX_DEBUG2("-->CMPXMessageItem::~CMPXMessageItem 0x%08x", this);
+    if (iMsg)
+        {
+        MPX_DEBUG3("CMPXMessageItem::~CMPXMessageItem msg 0x%08x, msgHandle 0x%08x",
+                   iMsg, iMsg->Data());
+
+        delete iMsg;
+        iMsg = NULL;
+        }
+    MPX_DEBUG2("<--CMPXMessageItem::~CMPXMessageItem 0x%08x", this);
+    }
+
+void CMPXMessageItem::ConstructL(const CMPXMessage* aMsg)
+    {
+    MPX_FUNC_EX("CMPXMessageItem::ConstructL");
+    iMsg = aMsg ? CMPXMessage::NewL(*aMsg) : NULL;
+    }
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXMessageQueue* CMPXMessageQueue::NewL()
+    {
+    CMPXMessageQueue* self = new ( ELeave ) CMPXMessageQueue();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// C++ constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXMessageQueue::CMPXMessageQueue()
+:   iMsgs(CMPXMessageItem::Offset()),
+    iFailure(KErrNone)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// Second-phase constructor.
+// ----------------------------------------------------------------------------
+//
+void CMPXMessageQueue::ConstructL()
+    {
+    MPX_FUNC_EX("CMPXMessageQueue::ConstructL");
+    }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXMessageQueue::~CMPXMessageQueue()
+    {
+    MPX_FUNC_EX("CMPXMessageQueue::~CMPXMessageQueue()");
+    Reset();
+    }
+
+// ----------------------------------------------------------------------------
+// Send next message request from client
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXMessageQueue::SendNext(const RMessage2& aMsgRequest)
+    {
+    MPX_FUNC_EX("CMPXMessageQueue::SendNext()");
+    MPX_ASSERT(iMsgRequest.IsNull());
+    iMsgRequest = aMsgRequest;
+    if (!iMsgs.IsEmpty())
+        {
+        Send();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// Adds a message into the queue and sends the message if slot is available
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXMessageQueue::Add(const CMPXMessage* aMessage, TInt aError)
+    {
+    // aMessage should not be NULL and aError is KErrNone
+    MPX_ASSERT(aMessage || aError);
+    MPX_FUNC_EX("CMPXMessageQueue::Add()");
+    CMPXMessageItem* item(NULL);
+    TRAPD(err, item = CMPXMessageItem::NewL(aMessage, aError));
+    if (KErrNone==err)
+        {
+        iMsgs.AddLast(*item);
+#ifdef _DEBUG
+        MPX_DEBUG3("CMPXMessageQueue::Add 0x%08x, items %d", this, ++iCount);
+#endif
+        }//else failed to create message item.
+    else
+        {
+        MPX_DEBUG2("CMPXMessageQueue::Add Failed to create message item %d", err);
+        }
+
+    if (KErrNone!=err && KErrNone==iFailure)
+        { // Set the failure code
+        iFailure = err;
+        }
+
+    if (!iMsgRequest.IsNull())
+        { // outstanding request
+        Send();
+        } // else client has not finished current message yet
+    }
+
+// ----------------------------------------------------------------------------
+// Reset message queue
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXMessageQueue::Reset()
+    {
+    MPX_FUNC_EX("CMPXMessageQueue::Reset()");
+    if (!iMsgRequest.IsNull())
+        {
+        iMsgRequest.Complete(KErrCancel);
+        }
+    delete iMsgSent;
+    iMsgSent = NULL;
+    TSglQueIter<CMPXMessageItem> iter(iMsgs);
+    CMPXMessageItem* msgItem=NULL;
+    while ((msgItem=iter++) != NULL) // Compiler on warning while(msgItem==iter++)
+        {
+        delete msgItem;
+        }
+    iMsgs.Reset();
+    }
+
+// ----------------------------------------------------------------------------
+// Send a message
+// ----------------------------------------------------------------------------
+//
+void CMPXMessageQueue::Send()
+    {
+    MPX_DEBUG3("-->CMPXMessageQueue::Send() 0x%08x, iMsgSent 0x%08x",
+              this, iMsgSent);
+    delete iMsgSent;
+    iMsgSent = NULL;
+    TInt data(0);
+    TInt err(KErrNone);
+    if (iFailure)
+        {
+        err=iFailure;
+        iFailure = KErrNone; // Reset failure code
+        }
+    else
+        {
+        MPX_ASSERT(!iMsgs.IsEmpty());
+        iMsgSent = iMsgs.First();
+        iMsgs.Remove(*iMsgSent);
+#ifdef _DEBUG
+        MPX_DEBUG4("CMPXMessageQueue::Send 0x%08x, msg 0x%08x, items %d",
+                    this, iMsgSent->Message(), --iCount);
+#endif
+        if (iMsgSent->Message())
+            {
+            data = iMsgSent->Message()->Data();
+            MPX_ASSERT(data>0);
+#ifdef _DEBUG
+            CMPXMessage* msg = iMsgSent->Message();
+            TMPXMessageId* pId = msg->Value<TMPXMessageId>(KMPXMessageGeneralId);
+            if (pId)
+                {
+                TInt id = static_cast<TInt>(*pId);
+                MPX_DEBUG5("CMPXMessageQueue::Send msg item 0x%08x, msg 0x%08x, msgHandle 0x%08x, msgId 0x%08x",
+                        iMsgSent, iMsgSent->Message(), data, id);
+                if (id==KMPXMessageGeneral)
+                    {
+                    MPX_ASSERT(msg->IsSupported(KMPXMessageGeneralEvent));
+                    TInt* pEvent = msg->Value<TInt>(KMPXMessageGeneralEvent);
+                    MPX_ASSERT(msg->IsSupported(KMPXMessageGeneralType));
+                    TInt* pType = msg->Value<TInt>(KMPXMessageGeneralType);
+                    MPX_ASSERT(msg->IsSupported(KMPXMessageGeneralData));
+                    TInt* pData = msg->Value<TInt>(KMPXMessageGeneralData);
+                    if (pEvent && pType && pData)
+                        {
+                        MPX_DEBUG5("CMPXMessageQueue::Send general msg item 0x%08x, event %d, type %d, data %d",
+                                    iMsgSent, *pEvent, *pType, *pData);
+                        }
+                    else
+                        {
+                        MPX_DEBUG1("CMPXMessageQueue::Send OOM");
+                        }
+                    }
+                }
+            else
+                {
+                MPX_DEBUG1("CMPXMessageQueue::Send OOM");
+                }
+#endif
+            } // else NULL message
+        else // else NULL message
+            {
+            MPX_ASSERT(iMsgSent->Error());
+            MPX_DEBUG3("CMPXMessageQueue::Send NULL message 0x%08x, err %d",
+                       this, iMsgSent->Error());
+            }
+        err = iMsgSent->Error();
+        }
+
+    TPckgC<TInt> dataPkg(data);
+    TPckgC<TInt> errPkg(err);
+    TInt ret = (iMsgRequest.Write(0, dataPkg));
+    if (!ret)
+        {
+        ret = iMsgRequest.Write(1, errPkg);
+        }
+#ifdef _DEBUG
+    if (ret)
+        {
+        MPX_DEBUG1("CMPXMessageQueue::Send Failed to write data");
+        }
+#endif
+    iMsgRequest.Complete(ret);
+    MPX_DEBUG5("<--CMPXMessageQueue::Send() 0x%08x, sentMsgHandle 0x%08x, sentError %d,  sentRet %d",
+               this, data, err, ret);
+    }
+
+// End of file