diff -r 000000000000 -r 08ec8eefde2f persistentstorage/centralrepository/cenrepsrv/srvsess.cpp --- /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(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 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(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 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(const_cast(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(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(TServerResources::iPerfTestMgr.Entries()), + KCentRepPerfTestArraySize * sizeof(TUint32)); + TInt ret = aMessage.Write(1, p); + if (ret == KErrNone) + { + TUint lastCompleteAccess = TServerResources::iPerfTestMgr.LastCompleteAccess(); + TPckg 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 pCount(count); + + TInt err = aMessage.Write(1, pCount); + if(err == KErrNone && count > 0) + { + TPtrC8 pBuf(reinterpret_cast(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__ +