persistentstorage/centralrepository/cenrepsrv/srvsess.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/centralrepository/cenrepsrv/srvsess.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,330 @@
+// Copyright (c) 2004-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:
+//
+
+#include "panic.h"
+#include "srvreqs.h"
+#include "sessmgr.h"
+#include "cachemgr.h"
+#include "srvsubsess.h"
+#include "srvsess.h"
+
+CServerSession::~CServerSession()
+	{
+	// Delete the subsession index.
+	delete iSubSessionIx;
+	
+	//Delete the subsession container via the CObjectConIx's remove function  
+	((CSessionManager*)Server())->RemoveContainer(iContainer);
+	}
+
+//Called by client/server framework after session has been successfully created.
+//In effect, a second-phase constructor.
+//Creates the object index and the object container for this session.
+void CServerSession::CreateL()
+	{
+	// Create new object index
+	iSubSessionIx = CObjectIx::NewL();
+	
+	// Initialize the object container
+	// using the object container index in the server.
+	iContainer = ((CSessionManager*)Server())->NewContainerL();
+	}
+
+//helper method to resolve and verify subsession using RMessage and subsession handle
+CServerSubSession* CServerSession::SubSessionFromHandle(const RMessage2& aMessage, TInt aHandle)
+	{
+	CServerSubSession* subSession = (CServerSubSession*)iSubSessionIx->At(aHandle);
+	if (subSession == NULL)
+	    {
+		PanicClient(EBadSubsessionHandle, aMessage);	    
+	    }
+	    
+	return subSession;
+	}
+
+// if ServiceL Leaves, execution resumes in this method.
+// this allows us to panic clients using bad descriptors, to deal with OOM conditions
+// and to fail transactions with the correct reason: OOM etc.
+void CServerSession::ServiceError(const RMessage2 &aMessage, TInt aError)
+	{
+	TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
+
+	// If we have failed during initialisation the subsession is no longer available.
+	// Perform additional cleanup by removing the subsession's handle from the server's 
+	// subsession index. 
+	if (fn == EInitialise)
+		{
+		// Retrieve handle
+		TPckgBuf<TInt> handlePckg;
+		TRAPD(res,aMessage.ReadL(3,handlePckg));
+		 
+		if (res == KErrNone)
+		 	{
+		 	TInt subSessionHandle = handlePckg();
+			iSubSessionIx->Remove(subSessionHandle);
+		 	}
+		#ifdef _DEBUG
+			else
+				{
+				RDebug::Print(_L("CServerSession::ServiceError - Can't remove subsession handle; aError = %d; res = %d"), aError, res); 
+				}   	
+		#endif 	 
+		}
+	
+	//under following conditions the subsession handles the error
+	if(fn > EInitialise && fn < ELastInTable)
+		{
+		CServerSubSession* subSession = SubSessionFromHandle(aMessage, aMessage.Int3());
+		if(subSession)
+			{
+			subSession->ServiceError(aError);   
+			}
+		#ifdef _DEBUG
+			else
+				{
+				RDebug::Print(_L("CServerSession::ServiceError - bad subsession handle. aError = %d"), aError); 
+				}   	
+		#endif  
+		}
+#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS		
+	//for multi ROFS instead of leaving we panic the client instead
+	switch (aError)
+		{
+		case KErrMultiRofsOldCreUsed:
+			PanicClient(EMultiRofsPanicOldCre,aMessage);
+			return;
+		case KErrMultiRofsGlobalOverride:
+			PanicClient(EMultiRofsPanicGlobalOverride,aMessage);
+			return;
+		case KErrMultiRofsTypeOverride:
+			PanicClient(EMultiRofsPanicTypeOveride,aMessage);
+			return;
+		case KErrMultiRofsIllegalRofs:
+			PanicClient(EMultiRofsPanicIllegalRofs,aMessage);
+			return;				
+		}
+#endif				
+		
+	CSession2::ServiceError(aMessage, aError);
+	}
+
+void CServerSession::ServiceL(const RMessage2& aMessage)
+	{
+	TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
+	
+#if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
+	if (fn == EGetSetParameters)
+		{
+		TInt r = GetSetParameters(aMessage);
+		aMessage.Complete(r);
+		return;
+		}
+#endif
+
+	if(fn > ELastInTable)
+		{
+		PanicClient(EBadMessageNumber, aMessage);
+		}
+	
+	CServerSubSession* subSession = NULL;
+
+#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
+	TUint32 startTick=0;
+	TUid repUid;
+	startTick=User::FastCounter();
+#endif
+	PERF_TEST_EVENT_START(subSession, aMessage);
+
+	if(fn == EInitialise)
+		{
+		//create subsession
+		subSession = NewSubSessionL(aMessage);
+#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)		
+		repUid=TUid::Uid(aMessage.Int0());
+		subSession->iRepositoryUid=repUid;
+#endif		
+		}
+	else
+		{
+		subSession = SubSessionFromHandle(aMessage, aMessage.Int3());
+#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
+		repUid=subSession->iRepositoryUid;
+#endif		
+		}
+
+	if(subSession)
+		{
+		
+		TInt r = KErrNone;
+		
+		if(fn == EClose)
+			{
+			//delete subsession	
+			DeleteSubSession(aMessage.Int3());
+			}
+		else
+			{
+			//ask subsession to handle the message
+			r = subSession->ServiceL(aMessage);
+			}
+
+		PERF_TEST_EVENT_END(subSession, aMessage);
+	
+#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
+		TUint32 endTick=User::FastCounter();
+		RDebug::Print(_L("[CENTREP],TimeStamp=,%d,Repository=,%x,Function=,%d,TickCount=,%d"),startTick,repUid.iUid,fn,endTick-startTick);
+#endif
+		if (r != CServerSubSession::KDontCompleteMessage)
+			{
+			aMessage.Complete(r);
+			}
+		}
+	//If (subsession == NULL) we don't need to complete the message, as the message is completed already when the client panicked
+	#ifdef _DEBUG   
+		else
+			{
+			RDebug::Print(_L("CServerSession::ServiceL - bad subsession handle. TServerRequest = %d"), fn); 
+			}
+	#endif
+	}
+
+//Creates a new subsession object, and writes its handle to the message.
+//A subsession object is the server side "partner" to the client side subsession.
+//On return last parameter of aMessage is filled with the handle of the subsession
+//and handle is also returned
+CServerSubSession* CServerSession::NewSubSessionL(const RMessage2& aMessage)
+	{
+	//create a new subsession
+	CServerSubSession* subSession = new (ELeave) CServerSubSession(this);
+	CleanupStack::PushL(subSession);
+	
+	//add the subsession object to this session's object container to generate a unique ID
+	iContainer->AddL(subSession);
+	CleanupStack::Pop(subSession);
+	
+	//add the object to the subsessions index, this returns a unique handle so that we can
+	//refer to the object later
+	TInt handle = iSubSessionIx->AddL(subSession);
+	
+	//write the handle to the client's message
+	TPckgBuf<TInt> handlePckg(handle);
+	TRAPD(res,aMessage.WriteL(3,handlePckg));
+	if (res!=KErrNone)
+		{
+		iSubSessionIx->Remove(handle);
+		PanicClient(EBadSubsessionHandle, aMessage);
+		subSession = NULL;
+		}
+
+	return subSession;
+	}
+	
+//Deletes a subsession object through its handle.
+void CServerSession::DeleteSubSession(TInt aHandle)
+	{
+	iSubSessionIx->Remove(aHandle);
+	}
+	
+inline CSessionManager* CServerSession::Server()
+	{
+	return static_cast<CSessionManager*>(const_cast<CServer2*>(CSession2::Server()));
+	}
+
+#if defined(__CENTREP_SERVER_PERFTEST__) || defined (__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
+// GetSetParameters
+// The function code EGetSetParameters is a generic msg reserved
+// for testing purpose. Int0 specifies the function to perform.
+TInt CServerSession::GetSetParameters(const TClientRequest& aMessage)
+	{
+	TServerGetSetParametersSubCmd cmd = static_cast<TServerGetSetParametersSubCmd>(aMessage.Int0());
+
+#ifdef __CENTREP_SERVER_PERFTEST__
+	if (cmd == EGetPerfResults)
+		{
+		TInt desSize = aMessage.GetDesMaxLength(1);
+		TInt numVals = desSize / sizeof(TUint32);
+		if (numVals < KCentRepPerfTestArraySize)
+			{
+			return KErrOverflow;
+			}
+		TPtrC8 p(reinterpret_cast<const TUint8*>(TServerResources::iPerfTestMgr.Entries()),
+				   KCentRepPerfTestArraySize * sizeof(TUint32));
+		TInt ret = aMessage.Write(1, p);
+		if (ret == KErrNone)
+			{
+			TUint lastCompleteAccess = TServerResources::iPerfTestMgr.LastCompleteAccess();
+			TPckg<TUint> p2(lastCompleteAccess);
+			ret = aMessage.Write(2, p2);
+			}
+		return ret;
+		}
+	else if (cmd == ERestartPerfTests)
+		{
+		TServerResources::iPerfTestMgr.Reset();
+		return KErrNone;
+		}
+	else if (cmd == EStopPerfTests)
+		{
+		TServerResources::iPerfTestMgr.Stop();
+		return KErrNone;
+		}
+#endif // __CENTREP_SERVER_PERFTEST__
+
+#ifdef __CENTREP_SERVER_MEMTEST__
+	if(cmd == ERestartMemTests)
+		{
+		TServerResources::StartRecordTimerResult();
+		return KErrNone;
+		}
+	else if(cmd == ESingleMemTest)
+		{
+		RECORD_HEAP_SIZE(EMemLcnOnDemand, aMessage.Int1());
+		return KErrNone;
+		}
+	else if(cmd == EGetMemResults)
+		{
+		TInt count = TServerResources::iMemTestDataCount;
+		TPckg<TInt> pCount(count);
+		
+		TInt err = aMessage.Write(1, pCount);
+		if(err == KErrNone && count > 0)
+			{
+			TPtrC8 pBuf(reinterpret_cast<TUint8*>(TServerResources::iMemTestData), (TServerResources::iMemTestDataCount)*sizeof(TInt32));
+			err = aMessage.Write(2, pBuf);
+			}
+		// Stop recording results
+		TServerResources::StopRecordTimerResult();
+		return err;
+		}
+#endif // __CENTREP_SERVER_MEMTEST__
+
+#ifdef __CENTREP_SERVER_CACHETEST__
+	if (cmd == EEnableCache)
+		{
+		// First parameter is Timer Interval, second is cache size
+		TServerResources::iCacheManager->EnableCache(aMessage.Int1(), aMessage.Int2());
+		return KErrNone;
+		}
+	else if (cmd == EDisableCache)
+		{
+		TServerResources::iCacheManager->DisableCache(ETrue);
+		return KErrNone;
+		}
+#endif  // __CENTREP_SERVER_CACHETEST__
+
+	return KErrNotSupported;
+	}
+#endif // __CENTREP_SERVER_PERFTEST__ || __CENTREP_SERVER_MEMTEST__ || __CENTREP_SERVER_CACHETEST__
+