diff -r 000000000000 -r e686773b3f54 phonebookengines/contactsmodel/cntsrv/src/CCntEventQueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/contactsmodel/cntsrv/src/CCntEventQueue.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,178 @@ +// Copyright (c) 2005-2009 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: +// + +/** + @file + @internalComponent + @released +*/ + + +#include "CCntEventQueue.h" +#include "CCntServer.h" +#include "CCntLogger.h" + + +extern void DebugLogNotification(const TDesC& aMethod, const TContactDbObserverEvent &aEvent); + + +CEventQueue::CEventQueue() + : iEvents(KCntEventGranularity) + { + } + + +CEventQueue::~CEventQueue() + { + iEvents.Close(); + } + + +void CEventQueue::QueueEvent(const TContactDbObserverEvent &aEvent) + { + // Flush the queue - there's no point in sending out all the preceeding + // events when the an Unknown Changes event is being sent. + // Unknown changes means that there are too many events to propagate and + // the client should resync all its cached data. + if (aEvent.iType == EContactDbObserverEventUnknownChanges) + { + Flush(); + } + + // Is the queue in order, if not then return (no event will be sent) + if (Flag(EQueueError)) + { + return; + } + + // Can we send the event right away, i.e. do we have an outstanding request + if (Flag(EValidEventMsg)) + { + SendEvent(aEvent); + }// Is the queue full? If so set flag EQueueError and return + else if (iEvents.Count() > KMaxNumberOfEventsInEventQueue) + { + + DEBUG_PRINTDN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] ->X"), aEvent); + + Flush(); + SetFlag(EQueueError); + }// Otherwise can we add the request to the queue + else if (iEvents.Append(aEvent)!=KErrNone) + { + SetFlag(EQueueError); + } +#if defined(__VERBOSE_DEBUG__) + else + { + // If added then add it to log + DebugLogNotification(_L("[CNTMODEL] ->Q"), aEvent); + } +#endif + } + + +void CEventQueue::Flush() + { + iEvents.Reset(); + } + + +void CEventQueue::RequestEvent(const RMessage2& aMessage) + { + __ASSERT_DEBUG(!Flag(EValidEventMsg),User::Leave(KErrCompletion)); + if (!Flag(EValidEventMsg)) + { + iEventMsg=aMessage; + SetFlag(EValidEventMsg); + if (Flag(EQueueError)) + { + TContactDbObserverEvent errorEvent; + //EContactDbObserverEventUnknownChanges is indicating that the event queue is full + errorEvent.iType = EContactDbObserverEventUnknownChanges; + errorEvent.iContactId = KNullContactId; + errorEvent.iConnectionId = KCntNullConnectionId; + ClearFlag(EQueueError); + SendEvent(errorEvent); + } + else if (iEvents.Count()>0) + { + SendEvent(iEvents[0]); + iEvents.Remove(0); + } + else + { + //No events has happened, so there is nothing to tell the client, + //But to be able to test the API policing we will complete the message + //if it contains the ApiPolicingTest flag and that the message is sent by the + //API policing test process sid(0x101F7784) + TInt isApiPolicingTest = aMessage.Int1(); + if (isApiPolicingTest == 666 && aMessage.SecureId() == 0x101F7784) + { + TContactDbObserverEvent nullEvent; + nullEvent.iType = EContactDbObserverEventNull; + nullEvent.iConnectionId = 0; + SendEvent(nullEvent); + } + } + } + } + + +void CEventQueue::CancelEventRequest() + { + if (Flag(EValidEventMsg)) + { + iEventMsg.Complete(KErrCancel); + ClearFlag(EValidEventMsg); + } + } + + +void CEventQueue::SendEvent(const TContactDbObserverEvent &aEvent) + { + DEBUG_PRINTDN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] Q->"), aEvent); + + TPckgC event(aEvent); + TInt err = iEventMsg.Write(0, event); + if (err != KErrNone) + { + // If there is an error caused, for example, by the client dying, just log the error code. + DEBUG_PRINT2(__VERBOSE_DEBUG__, _L("[CNTMODEL] iEventMsg.Write() error: %d"), err); + } + else + { + iEventMsg.Complete(KErrNone); + } + ClearFlag(EValidEventMsg); + } + + +TBool CEventQueue::Flag(TFlag aFlag) + { + return iFlags&aFlag; + } + + +void CEventQueue::SetFlag(TFlag aFlag) + { + iFlags|=aFlag; + } + + +void CEventQueue::ClearFlag(TFlag aFlag) + { + iFlags&=(~aFlag); + }