os/persistentdata/persistentstorage/centralrepository/cenrepsrv/srvsess.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "panic.h"
sl@0
    17
#include "srvreqs.h"
sl@0
    18
#include "sessmgr.h"
sl@0
    19
#include "cachemgr.h"
sl@0
    20
#include "srvsubsess.h"
sl@0
    21
#include "srvsess.h"
sl@0
    22
sl@0
    23
CServerSession::~CServerSession()
sl@0
    24
	{
sl@0
    25
	// Delete the subsession index.
sl@0
    26
	delete iSubSessionIx;
sl@0
    27
	
sl@0
    28
	//Delete the subsession container via the CObjectConIx's remove function  
sl@0
    29
	((CSessionManager*)Server())->RemoveContainer(iContainer);
sl@0
    30
	}
sl@0
    31
sl@0
    32
//Called by client/server framework after session has been successfully created.
sl@0
    33
//In effect, a second-phase constructor.
sl@0
    34
//Creates the object index and the object container for this session.
sl@0
    35
void CServerSession::CreateL()
sl@0
    36
	{
sl@0
    37
	// Create new object index
sl@0
    38
	iSubSessionIx = CObjectIx::NewL();
sl@0
    39
	
sl@0
    40
	// Initialize the object container
sl@0
    41
	// using the object container index in the server.
sl@0
    42
	iContainer = ((CSessionManager*)Server())->NewContainerL();
sl@0
    43
	}
sl@0
    44
sl@0
    45
//helper method to resolve and verify subsession using RMessage and subsession handle
sl@0
    46
CServerSubSession* CServerSession::SubSessionFromHandle(const RMessage2& aMessage, TInt aHandle)
sl@0
    47
	{
sl@0
    48
	CServerSubSession* subSession = (CServerSubSession*)iSubSessionIx->At(aHandle);
sl@0
    49
	if (subSession == NULL)
sl@0
    50
	    {
sl@0
    51
		PanicClient(EBadSubsessionHandle, aMessage);	    
sl@0
    52
	    }
sl@0
    53
	    
sl@0
    54
	return subSession;
sl@0
    55
	}
sl@0
    56
sl@0
    57
// if ServiceL Leaves, execution resumes in this method.
sl@0
    58
// this allows us to panic clients using bad descriptors, to deal with OOM conditions
sl@0
    59
// and to fail transactions with the correct reason: OOM etc.
sl@0
    60
void CServerSession::ServiceError(const RMessage2 &aMessage, TInt aError)
sl@0
    61
	{
sl@0
    62
	TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
sl@0
    63
sl@0
    64
	// If we have failed during initialisation the subsession is no longer available.
sl@0
    65
	// Perform additional cleanup by removing the subsession's handle from the server's 
sl@0
    66
	// subsession index. 
sl@0
    67
	if (fn == EInitialise)
sl@0
    68
		{
sl@0
    69
		// Retrieve handle
sl@0
    70
		TPckgBuf<TInt> handlePckg;
sl@0
    71
		TRAPD(res,aMessage.ReadL(3,handlePckg));
sl@0
    72
		 
sl@0
    73
		if (res == KErrNone)
sl@0
    74
		 	{
sl@0
    75
		 	TInt subSessionHandle = handlePckg();
sl@0
    76
			iSubSessionIx->Remove(subSessionHandle);
sl@0
    77
		 	}
sl@0
    78
		#ifdef _DEBUG
sl@0
    79
			else
sl@0
    80
				{
sl@0
    81
				RDebug::Print(_L("CServerSession::ServiceError - Can't remove subsession handle; aError = %d; res = %d"), aError, res); 
sl@0
    82
				}   	
sl@0
    83
		#endif 	 
sl@0
    84
		}
sl@0
    85
	
sl@0
    86
	//under following conditions the subsession handles the error
sl@0
    87
	if(fn > EInitialise && fn < ELastInTable)
sl@0
    88
		{
sl@0
    89
		CServerSubSession* subSession = SubSessionFromHandle(aMessage, aMessage.Int3());
sl@0
    90
		if(subSession)
sl@0
    91
			{
sl@0
    92
			subSession->ServiceError(aError);   
sl@0
    93
			}
sl@0
    94
		#ifdef _DEBUG
sl@0
    95
			else
sl@0
    96
				{
sl@0
    97
				RDebug::Print(_L("CServerSession::ServiceError - bad subsession handle. aError = %d"), aError); 
sl@0
    98
				}   	
sl@0
    99
		#endif  
sl@0
   100
		}
sl@0
   101
#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS		
sl@0
   102
	//for multi ROFS instead of leaving we panic the client instead
sl@0
   103
	switch (aError)
sl@0
   104
		{
sl@0
   105
		case KErrMultiRofsOldCreUsed:
sl@0
   106
			PanicClient(EMultiRofsPanicOldCre,aMessage);
sl@0
   107
			return;
sl@0
   108
		case KErrMultiRofsGlobalOverride:
sl@0
   109
			PanicClient(EMultiRofsPanicGlobalOverride,aMessage);
sl@0
   110
			return;
sl@0
   111
		case KErrMultiRofsTypeOverride:
sl@0
   112
			PanicClient(EMultiRofsPanicTypeOveride,aMessage);
sl@0
   113
			return;
sl@0
   114
		case KErrMultiRofsIllegalRofs:
sl@0
   115
			PanicClient(EMultiRofsPanicIllegalRofs,aMessage);
sl@0
   116
			return;				
sl@0
   117
		}
sl@0
   118
#endif				
sl@0
   119
		
sl@0
   120
	CSession2::ServiceError(aMessage, aError);
sl@0
   121
	}
sl@0
   122
sl@0
   123
void CServerSession::ServiceL(const RMessage2& aMessage)
sl@0
   124
	{
sl@0
   125
	TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
sl@0
   126
	
sl@0
   127
#if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
sl@0
   128
	if (fn == EGetSetParameters)
sl@0
   129
		{
sl@0
   130
		TInt r = GetSetParameters(aMessage);
sl@0
   131
		aMessage.Complete(r);
sl@0
   132
		return;
sl@0
   133
		}
sl@0
   134
#endif
sl@0
   135
sl@0
   136
	if(fn > ELastInTable)
sl@0
   137
		{
sl@0
   138
		PanicClient(EBadMessageNumber, aMessage);
sl@0
   139
		}
sl@0
   140
	
sl@0
   141
	CServerSubSession* subSession = NULL;
sl@0
   142
sl@0
   143
#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
sl@0
   144
	TUint32 startTick=0;
sl@0
   145
	TUid repUid;
sl@0
   146
	startTick=User::FastCounter();
sl@0
   147
#endif
sl@0
   148
	PERF_TEST_EVENT_START(subSession, aMessage);
sl@0
   149
sl@0
   150
	if(fn == EInitialise)
sl@0
   151
		{
sl@0
   152
		//create subsession
sl@0
   153
		subSession = NewSubSessionL(aMessage);
sl@0
   154
#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)		
sl@0
   155
		repUid=TUid::Uid(aMessage.Int0());
sl@0
   156
		subSession->iRepositoryUid=repUid;
sl@0
   157
#endif		
sl@0
   158
		}
sl@0
   159
	else
sl@0
   160
		{
sl@0
   161
		subSession = SubSessionFromHandle(aMessage, aMessage.Int3());
sl@0
   162
#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
sl@0
   163
		repUid=subSession->iRepositoryUid;
sl@0
   164
#endif		
sl@0
   165
		}
sl@0
   166
sl@0
   167
	if(subSession)
sl@0
   168
		{
sl@0
   169
		
sl@0
   170
		TInt r = KErrNone;
sl@0
   171
		
sl@0
   172
		if(fn == EClose)
sl@0
   173
			{
sl@0
   174
			//delete subsession	
sl@0
   175
			DeleteSubSession(aMessage.Int3());
sl@0
   176
			}
sl@0
   177
		else
sl@0
   178
			{
sl@0
   179
			//ask subsession to handle the message
sl@0
   180
			r = subSession->ServiceL(aMessage);
sl@0
   181
			}
sl@0
   182
sl@0
   183
		PERF_TEST_EVENT_END(subSession, aMessage);
sl@0
   184
	
sl@0
   185
#if defined (SYMBIAN_CENTREP_SUPPORT_MULTIROFS) && defined(CENTREP_TRACE)
sl@0
   186
		TUint32 endTick=User::FastCounter();
sl@0
   187
		RDebug::Print(_L("[CENTREP],TimeStamp=,%d,Repository=,%x,Function=,%d,TickCount=,%d"),startTick,repUid.iUid,fn,endTick-startTick);
sl@0
   188
#endif
sl@0
   189
		if (r != CServerSubSession::KDontCompleteMessage)
sl@0
   190
			{
sl@0
   191
			aMessage.Complete(r);
sl@0
   192
			}
sl@0
   193
		}
sl@0
   194
	//If (subsession == NULL) we don't need to complete the message, as the message is completed already when the client panicked
sl@0
   195
	#ifdef _DEBUG   
sl@0
   196
		else
sl@0
   197
			{
sl@0
   198
			RDebug::Print(_L("CServerSession::ServiceL - bad subsession handle. TServerRequest = %d"), fn); 
sl@0
   199
			}
sl@0
   200
	#endif
sl@0
   201
	}
sl@0
   202
sl@0
   203
//Creates a new subsession object, and writes its handle to the message.
sl@0
   204
//A subsession object is the server side "partner" to the client side subsession.
sl@0
   205
//On return last parameter of aMessage is filled with the handle of the subsession
sl@0
   206
//and handle is also returned
sl@0
   207
CServerSubSession* CServerSession::NewSubSessionL(const RMessage2& aMessage)
sl@0
   208
	{
sl@0
   209
	//create a new subsession
sl@0
   210
	CServerSubSession* subSession = new (ELeave) CServerSubSession(this);
sl@0
   211
	CleanupStack::PushL(subSession);
sl@0
   212
	
sl@0
   213
	//add the subsession object to this session's object container to generate a unique ID
sl@0
   214
	iContainer->AddL(subSession);
sl@0
   215
	CleanupStack::Pop(subSession);
sl@0
   216
	
sl@0
   217
	//add the object to the subsessions index, this returns a unique handle so that we can
sl@0
   218
	//refer to the object later
sl@0
   219
	TInt handle = iSubSessionIx->AddL(subSession);
sl@0
   220
	
sl@0
   221
	//write the handle to the client's message
sl@0
   222
	TPckgBuf<TInt> handlePckg(handle);
sl@0
   223
	TRAPD(res,aMessage.WriteL(3,handlePckg));
sl@0
   224
	if (res!=KErrNone)
sl@0
   225
		{
sl@0
   226
		iSubSessionIx->Remove(handle);
sl@0
   227
		PanicClient(EBadSubsessionHandle, aMessage);
sl@0
   228
		subSession = NULL;
sl@0
   229
		}
sl@0
   230
sl@0
   231
	return subSession;
sl@0
   232
	}
sl@0
   233
	
sl@0
   234
//Deletes a subsession object through its handle.
sl@0
   235
void CServerSession::DeleteSubSession(TInt aHandle)
sl@0
   236
	{
sl@0
   237
	iSubSessionIx->Remove(aHandle);
sl@0
   238
	}
sl@0
   239
	
sl@0
   240
inline CSessionManager* CServerSession::Server()
sl@0
   241
	{
sl@0
   242
	return static_cast<CSessionManager*>(const_cast<CServer2*>(CSession2::Server()));
sl@0
   243
	}
sl@0
   244
sl@0
   245
#if defined(__CENTREP_SERVER_PERFTEST__) || defined (__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
sl@0
   246
// GetSetParameters
sl@0
   247
// The function code EGetSetParameters is a generic msg reserved
sl@0
   248
// for testing purpose. Int0 specifies the function to perform.
sl@0
   249
TInt CServerSession::GetSetParameters(const TClientRequest& aMessage)
sl@0
   250
	{
sl@0
   251
	TServerGetSetParametersSubCmd cmd = static_cast<TServerGetSetParametersSubCmd>(aMessage.Int0());
sl@0
   252
sl@0
   253
#ifdef __CENTREP_SERVER_PERFTEST__
sl@0
   254
	if (cmd == EGetPerfResults)
sl@0
   255
		{
sl@0
   256
		TInt desSize = aMessage.GetDesMaxLength(1);
sl@0
   257
		TInt numVals = desSize / sizeof(TUint32);
sl@0
   258
		if (numVals < KCentRepPerfTestArraySize)
sl@0
   259
			{
sl@0
   260
			return KErrOverflow;
sl@0
   261
			}
sl@0
   262
		TPtrC8 p(reinterpret_cast<const TUint8*>(TServerResources::iPerfTestMgr.Entries()),
sl@0
   263
				   KCentRepPerfTestArraySize * sizeof(TUint32));
sl@0
   264
		TInt ret = aMessage.Write(1, p);
sl@0
   265
		if (ret == KErrNone)
sl@0
   266
			{
sl@0
   267
			TUint lastCompleteAccess = TServerResources::iPerfTestMgr.LastCompleteAccess();
sl@0
   268
			TPckg<TUint> p2(lastCompleteAccess);
sl@0
   269
			ret = aMessage.Write(2, p2);
sl@0
   270
			}
sl@0
   271
		return ret;
sl@0
   272
		}
sl@0
   273
	else if (cmd == ERestartPerfTests)
sl@0
   274
		{
sl@0
   275
		TServerResources::iPerfTestMgr.Reset();
sl@0
   276
		return KErrNone;
sl@0
   277
		}
sl@0
   278
	else if (cmd == EStopPerfTests)
sl@0
   279
		{
sl@0
   280
		TServerResources::iPerfTestMgr.Stop();
sl@0
   281
		return KErrNone;
sl@0
   282
		}
sl@0
   283
#endif // __CENTREP_SERVER_PERFTEST__
sl@0
   284
sl@0
   285
#ifdef __CENTREP_SERVER_MEMTEST__
sl@0
   286
	if(cmd == ERestartMemTests)
sl@0
   287
		{
sl@0
   288
		TServerResources::StartRecordTimerResult();
sl@0
   289
		return KErrNone;
sl@0
   290
		}
sl@0
   291
	else if(cmd == ESingleMemTest)
sl@0
   292
		{
sl@0
   293
		RECORD_HEAP_SIZE(EMemLcnOnDemand, aMessage.Int1());
sl@0
   294
		return KErrNone;
sl@0
   295
		}
sl@0
   296
	else if(cmd == EGetMemResults)
sl@0
   297
		{
sl@0
   298
		TInt count = TServerResources::iMemTestDataCount;
sl@0
   299
		TPckg<TInt> pCount(count);
sl@0
   300
		
sl@0
   301
		TInt err = aMessage.Write(1, pCount);
sl@0
   302
		if(err == KErrNone && count > 0)
sl@0
   303
			{
sl@0
   304
			TPtrC8 pBuf(reinterpret_cast<TUint8*>(TServerResources::iMemTestData), (TServerResources::iMemTestDataCount)*sizeof(TInt32));
sl@0
   305
			err = aMessage.Write(2, pBuf);
sl@0
   306
			}
sl@0
   307
		// Stop recording results
sl@0
   308
		TServerResources::StopRecordTimerResult();
sl@0
   309
		return err;
sl@0
   310
		}
sl@0
   311
#endif // __CENTREP_SERVER_MEMTEST__
sl@0
   312
sl@0
   313
#ifdef __CENTREP_SERVER_CACHETEST__
sl@0
   314
	if (cmd == EEnableCache)
sl@0
   315
		{
sl@0
   316
		// First parameter is Timer Interval, second is cache size
sl@0
   317
		TServerResources::iCacheManager->EnableCache(aMessage.Int1(), aMessage.Int2());
sl@0
   318
		return KErrNone;
sl@0
   319
		}
sl@0
   320
	else if (cmd == EDisableCache)
sl@0
   321
		{
sl@0
   322
		TServerResources::iCacheManager->DisableCache(ETrue);
sl@0
   323
		return KErrNone;
sl@0
   324
		}
sl@0
   325
#endif  // __CENTREP_SERVER_CACHETEST__
sl@0
   326
sl@0
   327
	return KErrNotSupported;
sl@0
   328
	}
sl@0
   329
#endif // __CENTREP_SERVER_PERFTEST__ || __CENTREP_SERVER_MEMTEST__ || __CENTREP_SERVER_CACHETEST__
sl@0
   330