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