os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServViewChangeManager.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "LogServViewChangeManager.h"
    17 #include <s32mem.h>
    18 #include "logservpanic.h"
    19 #include "LogServDatabaseChangeInterface.h"
    20 
    21 // Constants
    22 const TInt KLogServViewChangeDefinitionGranularity = 10;
    23 const TInt KLogServViewChangeQueueGranularity = 3;
    24 const TInt KLogServViewChangeBufferGranularity = 40;
    25 
    26 
    27 /////////////////////////////////////////////////////////////////////////////////////////
    28 // -----> CLogServViewChangeManager (source)
    29 /////////////////////////////////////////////////////////////////////////////////////////
    30 
    31 CLogServViewChangeManager::CLogServViewChangeManager(MLogServDatabaseChangeInterface& aChangeInterface)
    32 :	iChangeInterface(aChangeInterface), iPendingChanges(KLogServViewChangeQueueGranularity)
    33 	{
    34 	}
    35 
    36 CLogServViewChangeManager::~CLogServViewChangeManager()
    37 	{
    38 	delete iTransientChangeDefinition;
    39 	//
    40 	iPendingChanges.ResetAndDestroy();
    41 	iPendingChanges.Close();
    42 	}
    43 
    44 void CLogServViewChangeManager::ConstructL()
    45 	{
    46 	iTransientChangeDefinition = CLogChangeDefinition::NewL(KLogServViewChangeDefinitionGranularity);
    47 	}
    48 
    49 CLogServViewChangeManager* CLogServViewChangeManager::NewL(MLogServDatabaseChangeInterface& aChangeInterface)
    50 	{
    51 	CLogServViewChangeManager* self = new(ELeave) CLogServViewChangeManager(aChangeInterface);
    52 	CleanupStack::PushL(self);
    53 	self->ConstructL();
    54 	CleanupStack::Pop(self);
    55 	return self;
    56 	}
    57 
    58 /////////////////////////////////////////////////////////////////////////////////////////
    59 /////////////////////////////////////////////////////////////////////////////////////////
    60 /////////////////////////////////////////////////////////////////////////////////////////
    61 
    62 void CLogServViewChangeManager::ChangeTransactionPrepare()
    63 	{
    64 	iTransientChangeDefinition->Reset();
    65 	}
    66 
    67 void CLogServViewChangeManager::ChangeTransactionSubmitL(TLogId aId, TLogDatabaseChangeType aType, TInt aViewIndex)
    68 	{
    69 	iTransientChangeDefinition->AddL(aId, aType, aViewIndex);
    70 	}
    71 
    72 void CLogServViewChangeManager::ChangeTransactionCommitL()
    73 	{
    74 	// We can only tell the client-side view change observer about the changes if:
    75 	//
    76 	// (2) we actually have something to tell the client views (some changes)
    77 	// (3) we have an outstanding client-side change message pointer
    78 	//
    79 	const TInt count = iTransientChangeDefinition->Count();
    80 	if	(count > 0) // (2)
    81 		{
    82 		// Do we have any existing pending changes? We can't alter the contents of the
    83 		// first pending change, since the client may already be preparing a client-side
    84 		// buffer of the requisite size. We can, however, combine the 2nd batch of changes
    85 		// with this new set so there is less IPC required (although more memory).
    86 		const TInt pendingChangeCount = iPendingChanges.Count();
    87 		if	(pendingChangeCount >= 2)
    88 			{
    89 			CLogChangeDefinition* changeDef = CLogChangeDefinition::NewL();
    90 			CleanupStack::PushL(changeDef);
    91 			//
    92 			CBufBase* buffer = iPendingChanges[1];
    93 			RBufReadStream readStream(*buffer);
    94 			//
    95 			readStream >> *changeDef;
    96 			
    97 			// Add new changes
    98 			TLogId logId = KLogNullId;
    99 			TLogDatabaseChangeType type = ELogChangeTypeUndefined;
   100 			TInt viewIndex = 0;
   101 			//
   102 			for(TInt i=0; i<count; i++)
   103 				{
   104 				type = iTransientChangeDefinition->At(i, logId, viewIndex);
   105 				changeDef->AddL(logId, type, viewIndex);
   106 				}
   107 
   108 			// Write the whole lot out again
   109 			buffer->Delete(0, buffer->Size());
   110 
   111 			RBufWriteStream writeStream(*buffer);
   112 			writeStream << *changeDef;
   113 			buffer->Compress();
   114 			CleanupStack::PopAndDestroy(changeDef);
   115 			}
   116 		else
   117 			{
   118 			CBufBase* buffer = CBufFlat::NewL(KLogServViewChangeBufferGranularity);
   119 			CleanupStack::PushL(buffer);
   120 
   121 			// Externalize changes
   122 			RBufWriteStream stream(*buffer);
   123 			stream << *iTransientChangeDefinition; 
   124 			buffer->Compress();
   125 
   126 			// Add to container
   127 			User::LeaveIfError(iPendingChanges.Append(buffer));
   128 			CleanupStack::Pop(buffer);
   129 			}
   130 
   131 		// Notify if necessary - handles (3) implicitly
   132 		NotifyClient();
   133 		}
   134 
   135 	// Free some memory
   136 	iTransientChangeDefinition->Reset();
   137 	}
   138 
   139 /////////////////////////////////////////////////////////////////////////////////////////
   140 /////////////////////////////////////////////////////////////////////////////////////////
   141 /////////////////////////////////////////////////////////////////////////////////////////
   142 
   143 void CLogServViewChangeManager::DeliverChangesL(const RMessage2& aMessage)
   144 	{
   145 	if	(iPendingChanges.Count())
   146 		{
   147 		CBufBase* headItem = iPendingChanges[0];
   148 		//
   149 		const TInt expectedChangesSize = aMessage.Int1();
   150 		const TPtr8 pBufferContents(headItem->Ptr(0));
   151 
   152 		// Check buffer size is as we expect
   153 		if	(expectedChangesSize != pBufferContents.Size())
   154 			::PanicClientL(aMessage, ELogViewBadClientSideChangeBufferSize);
   155 		else
   156 			{
   157 			// Write back to client-side
   158 			aMessage.WriteL(2, pBufferContents);
   159 
   160 			// Remove the item
   161 			iPendingChanges.Remove(0);
   162 			delete headItem;
   163 			}
   164 		}
   165 	else
   166 		::PanicClientL(aMessage, ELogViewNoPendingChangesToDeliver);
   167 	}
   168 
   169 /////////////////////////////////////////////////////////////////////////////////////////
   170 /////////////////////////////////////////////////////////////////////////////////////////
   171 /////////////////////////////////////////////////////////////////////////////////////////
   172 
   173 void CLogServViewChangeManager::RequestChangeNotifications(const RMessage2& aMessage)
   174 	{
   175     if	(iClientSideChangeMessage == RMessagePtr2())
   176 		{
   177 		// Notify if we have any cached changes...
   178 		iClientSideChangeMessage = aMessage;
   179 		NotifyClient();
   180 		}
   181 	else
   182 		PanicClient(aMessage, ELogViewChangeRequestAlreadyIssued);
   183 	}
   184 
   185 void CLogServViewChangeManager::RequestChangeNotificationsCancel()
   186 	{
   187     if	(iClientSideChangeMessage != RMessagePtr2())
   188 		CompleteClientChangeMessage(KErrCancel);
   189 
   190 	// Zap all the pending changes too
   191 	iPendingChanges.ResetAndDestroy();
   192 	iPendingChanges.GranularCompress();
   193 	}
   194 
   195 /////////////////////////////////////////////////////////////////////////////////////////
   196 /////////////////////////////////////////////////////////////////////////////////////////
   197 /////////////////////////////////////////////////////////////////////////////////////////
   198 
   199 void CLogServViewChangeManager::NotifyClient()
   200 	{
   201 	const TInt count = iPendingChanges.Count();
   202     if	(iClientSideChangeMessage != RMessagePtr2() && count)
   203 		{
   204 		CBufBase* headItem = iPendingChanges[0];
   205 		const TInt messageSize = headItem->Size();
   206 		CompleteClientChangeMessage(messageSize);
   207 		}
   208 	}
   209 
   210 void CLogServViewChangeManager::CompleteClientChangeMessage(TInt aCompletionCode)
   211 	{
   212 	__ASSERT_ALWAYS(iClientSideChangeMessage != RMessagePtr2(), Panic(ELogViewNoClientChangeMessageOutstanding));
   213 	iClientSideChangeMessage.Complete(aCompletionCode);
   214 	}