diff -r 000000000000 -r a2952bb97e68 mpx/commonframework/common/src/mpxmessagequeue.cpp --- /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 +#ifdef _DEBUG +#include +#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 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(KMPXMessageGeneralId); + if (pId) + { + TInt id = static_cast(*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(KMPXMessageGeneralEvent); + MPX_ASSERT(msg->IsSupported(KMPXMessageGeneralType)); + TInt* pType = msg->Value(KMPXMessageGeneralType); + MPX_ASSERT(msg->IsSupported(KMPXMessageGeneralData)); + TInt* pData = msg->Value(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 dataPkg(data); + TPckgC 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