--- /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