kerneltest/e32test/demandpaging/t_svrpinning.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2008-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 the License "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 // e32test\demandpaging\t_svrpinning.cpp
       
    15 // Overview:
       
    16 // Test the pinning of RMessage descriptor arguments.
       
    17 // API Information:
       
    18 // RMessage2, RMessagePtr2, RSessionBase, CSession2, CServer2
       
    19 // Details:
       
    20 // Platforms/Drives/Compatibility:
       
    21 // All.
       
    22 // Assumptions/Requirement/Pre-requisites:
       
    23 // Failures and causes:
       
    24 // Base Port information:
       
    25 // 
       
    26 //
       
    27 
       
    28 #define __E32TEST_EXTENSION__
       
    29 
       
    30 #include <e32std.h>
       
    31 #include <e32std_private.h>
       
    32 #include <e32def.h>
       
    33 #include <e32def_private.h>
       
    34 #include <e32test.h>
       
    35 #include <e32panic.h>
       
    36 #include <dptest.h>
       
    37 #include <u32hal.h>
       
    38 #include <hal.h>
       
    39 
       
    40 const TInt KHeapMinSize=0x1000;
       
    41 const TInt KHeapMaxSize=0x1000;
       
    42 
       
    43 const TUint KPageSize = 0x1000;
       
    44 TInt gPageSize;
       
    45 TUint gPageMask;
       
    46 TBool gDataPagingSupport = EFalse;
       
    47 TBool gProcessPaged;
       
    48 enum TServerPinning
       
    49 	{
       
    50 	EServerDefault,
       
    51 	EServerPinning,
       
    52 	EServerNotPinning,
       
    53 	EServerSetPinningTooLate,
       
    54 	EServerPinningCount,
       
    55 	};
       
    56 TInt gServerPinningState;
       
    57 
       
    58 class CTestServer : public CServer2
       
    59 	{
       
    60 public:
       
    61 	CTestServer(TInt aPriority);
       
    62 protected:
       
    63 	//override the pure virtual functions:
       
    64 	virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
       
    65 	};
       
    66 
       
    67 
       
    68 class CTestSession : public CSession2
       
    69 	{
       
    70 public:
       
    71 	enum TTestMode
       
    72 		{
       
    73 		EStop,
       
    74 		ETestPinAll,
       
    75 		ETestPinEven,
       
    76 		ETestPinOdd,
       
    77 		ETestPin3,
       
    78 		ETestPin2,
       
    79 		ETestPin1,
       
    80 		ETestPin0,
       
    81 		ETestPinWritable,
       
    82 		ETestUnpinWritable,
       
    83 		ETestPinOOM,
       
    84 		ETestPinDefault,
       
    85 		ETestDeadServer,
       
    86 		};
       
    87 //Override pure virtual
       
    88 	IMPORT_C virtual void ServiceL(const RMessage2& aMessage);
       
    89 private:
       
    90 	TInt CheckDesPresent(const RMessage2& aMessage, TUint aArgIndex, TBool aExpected, TBool aWrite);
       
    91 	TInt CheckArgsPresent(const RMessage2& aMessage, TBool arg0Present, TBool arg1Present, TBool arg2Present, TBool arg3Present, TBool aWrite);
       
    92 	TBool iClientDied;
       
    93 	};
       
    94 
       
    95 
       
    96 class CMyActiveScheduler : public CActiveScheduler
       
    97 	{
       
    98 public:
       
    99 	virtual void Error(TInt anError) const; //override pure virtual error function
       
   100 	};
       
   101 
       
   102 
       
   103 class RSession : public RSessionBase
       
   104 	{
       
   105 public:
       
   106 	TInt PublicSendReceive(TInt aFunction, const TIpcArgs &aPtr)
       
   107 		{
       
   108 		return (SendReceive(aFunction, aPtr));
       
   109 		}
       
   110 	TInt PublicCreateSession(const TDesC& aServer,TInt aMessageSlots)
       
   111 		{
       
   112 		return (CreateSession(aServer,User::Version(),aMessageSlots));
       
   113 		}
       
   114 	};
       
   115 
       
   116 
       
   117 _LIT(KServerName,"CTestServer");
       
   118 
       
   119 TBool UpdateExpected(TBool aExpected)
       
   120 	{
       
   121 	if (!gDataPagingSupport												// Data paging is not supported so memory should always be present
       
   122 		|| gServerPinningState == EServerPinning						// The server is a pinning server.
       
   123 		/*|| (gServerPinningState == EServerDefault && !gProcessPaged)*/// The process isn't paged and default server policy
       
   124 		)
       
   125 		{
       
   126 		aExpected = ETrue;
       
   127 		}
       
   128 	return aExpected;
       
   129 	}
       
   130 
       
   131 
       
   132 CTestServer::CTestServer(TInt aPriority)
       
   133 //
       
   134 // Constructor - sets name
       
   135 //
       
   136 	: CServer2(aPriority)
       
   137 	{}
       
   138 
       
   139 CSession2* CTestServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/) const
       
   140 //
       
   141 // Virtual fn - checks version supported and creates a CTestSession
       
   142 //
       
   143 	{
       
   144 	TVersion version(KE32MajorVersionNumber,KE32MinorVersionNumber,KE32BuildVersionNumber);
       
   145 	if (User::QueryVersionSupported(version,aVersion)==EFalse)
       
   146 		User::Leave(KErrNotSupported);
       
   147 	CTestSession* newCTestSession = new CTestSession;
       
   148 	if (newCTestSession==NULL)
       
   149 		User::Panic(_L("NewSessionL failure"), KErrNoMemory);
       
   150 	return(newCTestSession);
       
   151 	}
       
   152 
       
   153 RSemaphore gSem;
       
   154 RSemaphore gSem1;
       
   155 
       
   156 TInt CTestSession::CheckDesPresent(const RMessage2& aMessage, TUint aArgIndex, TBool aExpected, TBool aWrite)
       
   157 	{
       
   158 	if (aExpected)
       
   159 		RDebug::Printf("  Checking message argument at %d is present", aArgIndex);
       
   160 	else
       
   161 		RDebug::Printf("  Checking message argument at %d is not present", aArgIndex);
       
   162 
       
   163 	// Get the length of the descriptor and verify it is as expected.
       
   164 	TInt length = aMessage.GetDesLength(aArgIndex);
       
   165 	if (length < KErrNone)
       
   166 		{
       
   167 		RDebug::Printf("  Error getting descriptor length %d", length);
       
   168 		return length;
       
   169 		}
       
   170 	if (length < 3)
       
   171 		{// The incorrect descriptor length.
       
   172 		RDebug::Printf("  Error - Descriptor length too small %d", length);
       
   173 		return KErrArgument;
       
   174 		}
       
   175 	if (!aWrite)
       
   176 		{// Now read the descriptor and verify that it is present or not.
       
   177 		TBuf8<5> des;
       
   178 		TInt r = aMessage.Read(aArgIndex, des);
       
   179 		TBool pass;
       
   180 		if (iClientDied)
       
   181 			pass = r == KErrDied || r == KErrBadDescriptor;
       
   182 		else
       
   183 			pass = r == (aExpected ? KErrNone : KErrBadDescriptor);
       
   184 		if (!pass)
       
   185 			{
       
   186 			RDebug::Printf("  Error reading descriptor data r %d", r);
       
   187 			return KErrGeneral;
       
   188 			}
       
   189 		if (r==KErrNone && (des[0] != 'a' || des[1] != 'r' || des[2] != 'g'))
       
   190 			{// The incorrect descriptor data has been passed.
       
   191 			RDebug::Printf("  Error in descriptor data is corrupt r %d", r);
       
   192 			return KErrArgument;
       
   193 			}
       
   194 		}
       
   195 	else
       
   196 		{// Now write to the maximum length of the descriptor.
       
   197 		TInt max = aMessage.GetDesMaxLength(aArgIndex);
       
   198 		if (max < 0)
       
   199 			{
       
   200 			RDebug::Printf("  Error getting descriptor max. length %d", max);
       
   201 			return length;
       
   202 			}
       
   203 		HBufC8* argTmp = HBufC8::New(max);
       
   204 		TPtr8 argPtr = argTmp->Des();
       
   205 		argPtr.SetLength(max);
       
   206 		for (TInt i = 0; i < max; i++)
       
   207 			argPtr[i] = (TUint8)aArgIndex;
       
   208 		TInt r = aMessage.Write(aArgIndex, argPtr);
       
   209 		TBool pass;
       
   210 		if (iClientDied)
       
   211 			pass = r == KErrDied || r == KErrBadDescriptor;
       
   212 		else
       
   213 			pass = r == (aExpected ? KErrNone : KErrBadDescriptor);
       
   214 		if (!pass)
       
   215 			{
       
   216 			RDebug::Printf("  Error writing to the descriptor data r %d", r);
       
   217 			return KErrGeneral;
       
   218 			}
       
   219 		}
       
   220 
       
   221 	if (!aExpected)
       
   222 		{// The client should have been killed as the data wasn't present.
       
   223 		if(!iClientDied)
       
   224 			User::After(500000); // allow time for client to die before next test
       
   225 		iClientDied = ETrue;
       
   226 		}
       
   227 	return KErrNone;
       
   228 	}
       
   229 
       
   230 TInt CTestSession::CheckArgsPresent(const RMessage2& aMessage, TBool arg0Present, TBool arg1Present, TBool arg2Present, TBool arg3Present, TBool aWrite=EFalse)
       
   231 	{
       
   232 	// Adjust the pinning status expected based on the default policies.
       
   233 	// (Must do this before anything else as UpdateExpected() accessed paged global data)
       
   234 	arg0Present = UpdateExpected(arg0Present);
       
   235 	arg1Present = UpdateExpected(arg1Present);
       
   236 	arg2Present = UpdateExpected(arg2Present);
       
   237 	arg3Present = UpdateExpected(arg3Present);
       
   238 
       
   239 	// Flush the cache so on paged systems, unpinned paged memory will be discarded.
       
   240 	DPTest::FlushCache();
       
   241 
       
   242 	TInt r = User::SetRealtimeState(User::ERealtimeStateOn);
       
   243 	if (r != KErrNone)
       
   244 		{
       
   245 		RDebug::Printf("Error setting realtime state r = %d", r);
       
   246 		return r;
       
   247 		}
       
   248 
       
   249 	r = CheckDesPresent(aMessage, 0, arg0Present, aWrite);
       
   250 	if (r == KErrNone)
       
   251 		r = CheckDesPresent(aMessage, 1, arg1Present, aWrite);
       
   252 	if (r == KErrNone)
       
   253 		r = CheckDesPresent(aMessage, 2, arg2Present, aWrite);
       
   254 	if (r == KErrNone)
       
   255 		r = CheckDesPresent(aMessage, 3, arg3Present, aWrite);
       
   256 
       
   257 	User::SetRealtimeState(User::ERealtimeStateOff);
       
   258 
       
   259 	return r;
       
   260 	}
       
   261 
       
   262 void CTestSession::ServiceL(const RMessage2& aMessage)
       
   263 //
       
   264 // Virtual message-handler
       
   265 //
       
   266 	{
       
   267 	TInt r = KErrNone;
       
   268 	iClientDied = EFalse;
       
   269 	switch (aMessage.Function())
       
   270 		{
       
   271 		case EStop:
       
   272 			CActiveScheduler::Stop();
       
   273 			break;
       
   274 		case ETestPinAll:
       
   275 			r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, ETrue);
       
   276 			break;
       
   277 		case ETestPinOdd:
       
   278 			r = CheckArgsPresent(aMessage, EFalse, ETrue, EFalse, ETrue);
       
   279 			break;
       
   280 		case ETestPinEven:
       
   281 			r = CheckArgsPresent(aMessage, ETrue, EFalse, ETrue, EFalse);
       
   282 			break;
       
   283 		case ETestPin3:
       
   284 			r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, EFalse);
       
   285 			break;
       
   286 		case ETestPin2:
       
   287 			r = CheckArgsPresent(aMessage, ETrue, ETrue, EFalse, EFalse);
       
   288 			break;
       
   289 		case ETestPin1:
       
   290 			r = CheckArgsPresent(aMessage, ETrue, EFalse, EFalse, EFalse);
       
   291 			break;
       
   292 		case ETestPin0:
       
   293 		case ETestPinDefault:
       
   294 			r = CheckArgsPresent(aMessage, EFalse, EFalse, EFalse, EFalse);
       
   295 			break;
       
   296 		case ETestPinWritable:
       
   297 			r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, ETrue, ETrue);
       
   298 			break;
       
   299 		case ETestUnpinWritable:
       
   300 			r = CheckArgsPresent(aMessage, EFalse, EFalse, EFalse, EFalse, ETrue);
       
   301 			break;
       
   302 		default:
       
   303 			r = KErrNotSupported;
       
   304 
       
   305 		}
       
   306  	aMessage.Complete(r);
       
   307 
       
   308 	// If descriptors aren't as expected then panic so the test will fail.
       
   309 	if (r != KErrNone)
       
   310 		User::Panic(_L("ServiceL failure"), r);
       
   311 	}
       
   312 
       
   313 // CTestSession funtions
       
   314 
       
   315 void CMyActiveScheduler::Error(TInt anError) const
       
   316 //
       
   317 // Virtual error handler
       
   318 //
       
   319 	{
       
   320 	User::Panic(_L("CMyActiveScheduer::Error"), anError);
       
   321 	}
       
   322 
       
   323 TInt ServerThread(TAny* aPinningAttrib)
       
   324 //
       
   325 // Passed as the server thread in 2 tests - sets up and runs CTestServer
       
   326 //
       
   327 	{
       
   328 	RTest test(_L("T_SVRPINNING...server"));
       
   329 	CMyActiveScheduler* pScheduler = new CMyActiveScheduler;
       
   330 	if (pScheduler == NULL)
       
   331 		{
       
   332 		gSem.Signal();
       
   333 		test(0);
       
   334 		}
       
   335 
       
   336 	CActiveScheduler::Install(pScheduler);
       
   337 
       
   338 	CTestServer* pServer = new CTestServer(0);
       
   339 	if (pServer == NULL)
       
   340 		{
       
   341 		gSem.Signal();
       
   342 		test(0);
       
   343 		}
       
   344 
       
   345 	// Set the pinning attributes of the server.
       
   346 	TServerPinning pinningAttrib = (TServerPinning)(TInt)aPinningAttrib;
       
   347 	switch (pinningAttrib)
       
   348 		{
       
   349 		case EServerDefault :
       
   350 		case EServerSetPinningTooLate :
       
   351 			break;
       
   352 		case EServerPinning :
       
   353 			pServer->SetPinClientDescriptors(ETrue);
       
   354 			break;
       
   355 		case EServerNotPinning :
       
   356 			pServer->SetPinClientDescriptors(EFalse);
       
   357 			break;
       
   358 		default :
       
   359 			break;
       
   360 		}
       
   361 
       
   362 	//Starting a CServer2 also Adds it to the ActiveScheduler
       
   363 	TInt r = pServer->Start(KServerName);
       
   364 	if (r != KErrNone)
       
   365 		{
       
   366 		gSem.Signal();
       
   367 		test(0);
       
   368 		}
       
   369 
       
   370 	if (pinningAttrib == EServerSetPinningTooLate)
       
   371 		{
       
   372 		pServer->SetPinClientDescriptors(EFalse);
       
   373 		}
       
   374 
       
   375 	test.Next(_L("Start ActiveScheduler and signal to client"));
       
   376 	test.Printf(_L("        There might be something going on beneath this window\n"));
       
   377 	gSem.Signal();
       
   378 	CActiveScheduler::Start();
       
   379 	test.Next(_L("Destroy ActiveScheduler"));
       
   380 	delete pScheduler;
       
   381 	delete pServer;
       
   382 
       
   383 	test.Close();
       
   384 
       
   385 	return (KErrNone);
       
   386 	}
       
   387 
       
   388 
       
   389 
       
   390 #include <e32svr.h>
       
   391 
       
   392 void dummyFunction(TUint8* /*a0*/, TUint8* /*a1*/, TUint8* /*a2*/, TUint8* /*a3*/, TUint8* /*a4*/, TUint8* /*a5*/)
       
   393 	{
       
   394 	}
       
   395 
       
   396 TInt ClientThread(TAny* aTestMode)
       
   397 //
       
   398 // Passed as the first client thread - signals the server to do several tests
       
   399 //
       
   400 	{
       
   401 	// Create the message arguments to be pinned.  Should be one of each type of
       
   402 	// descriptor to test that the pinning code can correctly pin each type 
       
   403 	// descriptor data.  Each descriptor's data should in a separate page in 
       
   404 	// thread's stack to ensure that access to each argument will cause a 
       
   405 	// separate page fault.
       
   406 
       
   407 	TUint8 argBufs[KPageSize*(6+2)]; // enough for 6 whole pages
       
   408 	TUint8* argBuf0 = (TUint8*)(TUintPtr(argBufs+gPageMask)&~gPageMask);
       
   409 	TUint8* argBuf1 = argBuf0+KPageSize;
       
   410 	TUint8* argBuf2 = argBuf1+KPageSize;
       
   411 	TUint8* argBuf3 = argBuf2+KPageSize;
       
   412 	TUint8* argBuf4 = argBuf3+KPageSize;
       
   413 	TUint8* argBuf5 = argBuf4+KPageSize;
       
   414 
       
   415 	argBuf0[0]='a'; argBuf0[1]='r'; argBuf0[2]='g'; argBuf0[3]='0'; argBuf0[4]='\0';
       
   416 	TPtr8 arg0(argBuf0, 5, 20);
       
   417 
       
   418 	TBufC8<5>& arg1 = *(TBufC8<5>*)argBuf1;
       
   419 	new (&arg1) TBufC8<5>((const TUint8*)"arg1");
       
   420 
       
   421 	argBuf2[0]='a'; argBuf2[1]='r'; argBuf2[2]='g'; argBuf2[3]='1'; argBuf2[4]='\0';
       
   422 	TPtrC8 arg2((const TUint8*)argBuf2);
       
   423 
       
   424 	TBuf8<50>& arg3 = *(TBuf8<50>*)argBuf3;
       
   425 	new (&arg3) TBuf8<50>((const TUint8*)"arg3");
       
   426 
       
   427 	// For some tests use this 5th and final type of descriptor.
       
   428 	HBufC8* argTmp = HBufC8::New(7);
       
   429 	*argTmp = (const TUint8*)"argTmp";
       
   430 	RBuf8 argTmpBuf(argTmp);
       
   431 
       
   432 	// Need a couple of extra writable argments
       
   433 	argBuf4[0]='a'; argBuf4[1]='r'; argBuf4[2]='g'; argBuf4[3]='4'; argBuf4[4]='\0';
       
   434 	TPtr8 arg4(argBuf4, 5, 20);
       
   435 	argBuf5[0]='a'; argBuf5[1]='r'; argBuf5[2]='g'; argBuf5[3]='5'; argBuf5[4]='\0';
       
   436 	TPtr8 arg5(argBuf5, 5, 20);
       
   437 
       
   438 	RTest test(_L("T_SVRPINNING...client"));
       
   439 	RSession session;
       
   440 	TInt r = session.PublicCreateSession(_L("CTestServer"),5);
       
   441 	if (r != KErrNone)
       
   442 		{
       
   443 		gSem.Signal();
       
   444 		test(0);
       
   445 		}
       
   446 
       
   447 	switch((TInt)aTestMode)
       
   448 		{
       
   449 		case CTestSession::ETestPinAll:
       
   450 			test.Printf(_L("Test pinning all args\n"));
       
   451 			r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs());
       
   452 			break;
       
   453 
       
   454 		case CTestSession::ETestPinOdd:
       
   455 			test.Printf(_L("Test pinning odd args\n"));
       
   456 			r = session.PublicSendReceive(CTestSession::ETestPinOdd, TIpcArgs(&arg0, &argTmpBuf, &arg2, &arg3).PinArgs(EFalse, ETrue, EFalse, ETrue));
       
   457 			break;
       
   458 
       
   459 		case CTestSession::ETestPinEven:
       
   460 			test.Printf(_L("Test pinning even args\n"));
       
   461 			r = session.PublicSendReceive(CTestSession::ETestPinEven, TIpcArgs(&arg0, &arg1, argTmp, &arg3).PinArgs(ETrue, EFalse, ETrue, EFalse));
       
   462 			break;
       
   463 
       
   464 		case CTestSession::ETestPin3:
       
   465 			test.Printf(_L("Test pinning 3 args\n"));
       
   466 			r = session.PublicSendReceive(CTestSession::ETestPin3, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs(ETrue, ETrue, ETrue, EFalse));
       
   467 			break;
       
   468 
       
   469 		case CTestSession::ETestPin2:
       
   470 			test.Printf(_L("Test pinning 2 args\n"));
       
   471 			r = session.PublicSendReceive(CTestSession::ETestPin2, TIpcArgs(argTmp, &arg1, &arg2, &arg3).PinArgs(ETrue, ETrue, EFalse, EFalse));
       
   472 			break;
       
   473 
       
   474 		case CTestSession::ETestPin1:
       
   475 			test.Printf(_L("Test pinning 1 args\n"));
       
   476 			r = session.PublicSendReceive(CTestSession::ETestPin1, TIpcArgs(&argTmpBuf, &arg1, &arg2, &arg3).PinArgs(ETrue, EFalse, EFalse, EFalse));
       
   477 			break;
       
   478 
       
   479 		case CTestSession::ETestPin0:
       
   480 			test.Printf(_L("Test pinning 0 args\n"));
       
   481 			r = session.PublicSendReceive(CTestSession::ETestPin0, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs(EFalse, EFalse, EFalse, EFalse));
       
   482 			break;
       
   483 
       
   484 		case CTestSession::ETestPinDefault:
       
   485 			test.Printf(_L("Test the default pinning policy of this server\n"));
       
   486 			r = session.PublicSendReceive(CTestSession::ETestPinDefault, TIpcArgs(&arg0, &arg1, &arg2, argTmp));
       
   487 			break;
       
   488 
       
   489 		case CTestSession::ETestPinWritable:
       
   490 			test.Printf(_L("Test writing to pinned descriptors\n"));
       
   491 			r = session.PublicSendReceive(CTestSession::ETestPinWritable, TIpcArgs(&arg0, &arg3, &arg4, &arg5).PinArgs(ETrue, ETrue, ETrue, ETrue));
       
   492 			// Verify the index of each argument has been written to each descriptor.
       
   493 			{
       
   494 			TUint maxLength = arg0.MaxLength();
       
   495 			test_Equal(maxLength, arg0.Length());
       
   496 			TUint j = 0;
       
   497 			for (; j < maxLength; j++)
       
   498 				test_Equal(0, arg0[j]);
       
   499 			maxLength = arg3.MaxLength();
       
   500 			test_Equal(maxLength, arg3.Length());
       
   501 			for (j = 0; j < maxLength; j++)
       
   502 				test_Equal(1, arg3[j]);
       
   503 			maxLength = arg4.MaxLength();
       
   504 			test_Equal(maxLength, arg4.Length());
       
   505 			for (j = 0; j < maxLength; j++)
       
   506 				test_Equal(2, arg4[j]);
       
   507 			maxLength = arg5.MaxLength();
       
   508 			test_Equal(maxLength, arg5.Length());
       
   509 			for (j = 0; j < maxLength; j++)
       
   510 				test_Equal(3, arg5[j]);
       
   511 			}
       
   512 			break;
       
   513 
       
   514 		case CTestSession::ETestUnpinWritable:
       
   515 			test.Printf(_L("Test writing to unpinned descriptors\n"));
       
   516 			r = session.PublicSendReceive(CTestSession::ETestUnpinWritable, TIpcArgs(&arg0, &arg3, &arg4, &arg5).PinArgs(EFalse, EFalse, EFalse, EFalse));
       
   517 			// Verify the index of each argument has been written to each descriptor.
       
   518 			// Unless this is a pinnning server than the thread will be panicked before we reach there.
       
   519 			{
       
   520 			TUint maxLength = arg0.MaxLength();
       
   521 			test_Equal(maxLength, arg0.Length());
       
   522 			TUint j = 0;
       
   523 			for (j = 0; j < maxLength; j++)
       
   524 				test_Equal(0, arg0[j]);
       
   525 			maxLength = arg3.MaxLength();
       
   526 			test_Equal(maxLength, arg3.Length());
       
   527 			for (j = 0; j < maxLength; j++)
       
   528 				test_Equal(1, arg3[j]);
       
   529 			maxLength = arg4.MaxLength();
       
   530 			test_Equal(maxLength, arg4.Length());
       
   531 			for (j = 0; j < maxLength; j++)
       
   532 				test_Equal(2, arg4[j]);
       
   533 			maxLength = arg5.MaxLength();
       
   534 			test_Equal(maxLength, arg5.Length());
       
   535 			for (j = 0; j < maxLength; j++)
       
   536 				test_Equal(3, arg5[j]);
       
   537 			}
       
   538 			break;
       
   539 
       
   540 		case CTestSession::ETestDeadServer:
       
   541 			test.Printf(_L("Test pinning to dead server\n"));
       
   542 			gSem.Signal();
       
   543 			gSem1.Wait();
       
   544 			r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs());
       
   545 			break;
       
   546 
       
   547 		case CTestSession::ETestPinOOM:
       
   548 			test.Printf(_L("Pinning OOM tests\n"));
       
   549 			__KHEAP_MARK;
       
   550 			const TUint KMaxKernelAllocations = 1024;
       
   551 			TUint i;
       
   552 			r = KErrNoMemory;
       
   553 			for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
       
   554 				{
       
   555 				__KHEAP_FAILNEXT(i);
       
   556 				r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs());
       
   557 				__KHEAP_RESET;
       
   558 				}
       
   559 			test.Printf(_L("SendReceive took %d tries\n"),i);
       
   560 			test_KErrNone(r);
       
   561 
       
   562 			__KHEAP_MARKEND;
       
   563 			break;
       
   564 		}
       
   565 
       
   566 	session.Close();
       
   567 	test.Close();
       
   568 	return r;
       
   569 	}
       
   570 
       
   571 
       
   572 GLDEF_C TInt E32Main()
       
   573 	{
       
   574 	RTest test(_L("T_SVRPINNING...main"));
       
   575 	test.Title();
       
   576 
       
   577 
       
   578 	if (DPTest::Attributes() & DPTest::ERomPaging)
       
   579 		test.Printf(_L("Rom paging supported\n"));
       
   580 	if (DPTest::Attributes() & DPTest::ECodePaging)
       
   581 		test.Printf(_L("Code paging supported\n"));
       
   582 	if (DPTest::Attributes() & DPTest::EDataPaging)
       
   583 		{
       
   584 		test.Printf(_L("Data paging supported\n"));
       
   585 		gDataPagingSupport = ETrue;
       
   586 		}
       
   587 
       
   588 	// Determine the data paging attribute.
       
   589 	RProcess process;	// Default to point to current process.
       
   590 	gProcessPaged = process.DefaultDataPaged();
       
   591 	test.Printf(_L("Process data paged %x\n"), gProcessPaged);
       
   592 
       
   593 	test.Start(_L("Test IPC message arguments pinning"));
       
   594 	test_KErrNone(HAL::Get(HAL::EMemoryPageSize, gPageSize));
       
   595 	gPageMask = gPageSize - 1;
       
   596 	test_Equal(KPageSize, gPageSize);
       
   597 	// Disable JIT as we are testing panics and don't want the emulator to hang.
       
   598 	TBool justInTime = User::JustInTime();
       
   599 	User::SetJustInTime(EFalse);
       
   600 
       
   601 	TBool exitFailure = EFalse;
       
   602 	for (	gServerPinningState = EServerDefault; 
       
   603 			gServerPinningState < EServerSetPinningTooLate && !exitFailure; 
       
   604 			gServerPinningState++)
       
   605 		{
       
   606 		// Create the server with the specified pinning mode.
       
   607 		switch (gServerPinningState)
       
   608 			{
       
   609 			case EServerDefault : 
       
   610 				test.Next(_L("Test server with default pinning policy"));
       
   611 				break;
       
   612 			case EServerPinning : 
       
   613 				test.Next(_L("Test server with pinning policy"));
       
   614 				break;
       
   615 			case EServerNotPinning : 
       
   616 				test.Next(_L("Test server with not pinning policy"));
       
   617 				break;
       
   618 			}
       
   619 		test_KErrNone(gSem.CreateLocal(0));
       
   620 		test_KErrNone(gSem1.CreateLocal(0));
       
   621 		// Create the server thread it needs to have a unpaged stack and heap.
       
   622 		TThreadCreateInfo serverInfo(_L("Server Thread"), ServerThread, KDefaultStackSize, (TAny*)gServerPinningState);
       
   623 		serverInfo.SetPaging(TThreadCreateInfo::EUnpaged);
       
   624 		serverInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize);
       
   625 		RThread serverThread;
       
   626 		test_KErrNone(serverThread.Create(serverInfo));
       
   627 		TRequestStatus serverStat;
       
   628 		serverThread.Logon(serverStat);
       
   629 		serverThread.Resume();
       
   630 
       
   631 		// Wait for the server to start and then create a session to it.
       
   632 		gSem.Wait();
       
   633 		RSession session;
       
   634 		test_KErrNone(session.PublicCreateSession(_L("CTestServer"),5));
       
   635 		
       
   636 		for (	TUint clientTest = CTestSession::ETestPinAll; 
       
   637 				clientTest <= CTestSession::ETestPinDefault && !exitFailure;
       
   638 				clientTest++)
       
   639 			{
       
   640 			// Create the client thread it needs to have a paged stack and heap.
       
   641 			TThreadCreateInfo clientInfo(_L("Client Thread"), ClientThread, 10 * gPageSize, (TAny*)clientTest);
       
   642 			clientInfo.SetPaging(TThreadCreateInfo::EPaged);
       
   643 			clientInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize);
       
   644 			RThread clientThread;
       
   645 			test_KErrNone(clientThread.Create(clientInfo));
       
   646 
       
   647 			TRequestStatus clientStat;
       
   648 			clientThread.Logon(clientStat);
       
   649 			clientThread.Resume();
       
   650 
       
   651 			// Wait for the client thread to end.
       
   652 			User::WaitForRequest(clientStat);
       
   653 
       
   654 			// If all the descriptor arguments were not pinned then the client 
       
   655 			// thread should have been panicked.
       
   656 			TBool expectPanic = (clientTest == CTestSession::ETestPinAll || 
       
   657 								clientTest == CTestSession::ETestPinWritable ||
       
   658 								clientTest == CTestSession::ETestPinOOM )? 0 : 1;
       
   659 			expectPanic = !UpdateExpected(!expectPanic);
       
   660 
       
   661 			TInt exitReason = clientThread.ExitReason();
       
   662 			TInt exitType = clientThread.ExitType();
       
   663 			if (expectPanic)
       
   664 				{
       
   665 				if (exitType != EExitPanic || 
       
   666 					exitReason != EIllegalFunctionForRealtimeThread ||
       
   667 					clientThread.ExitCategory() != _L("KERN-EXEC"))
       
   668 					{// Thread didn't panic as expected.
       
   669 					exitFailure = ETrue;
       
   670 					}
       
   671 				}
       
   672 			else
       
   673 				{
       
   674 				if (exitType != EExitKill || exitReason != KErrNone)
       
   675 					{// Thread didn't exit gracefully as expected.
       
   676 					exitFailure = ETrue;
       
   677 					}
       
   678 				}
       
   679 			CLOSE_AND_WAIT(clientThread);
       
   680 			}
       
   681 
       
   682 		test.Next(_L("Test client sending message to closed server"));
       
   683 		TThreadCreateInfo clientInfo(_L("Client Thread"), ClientThread, 10 * gPageSize, (TAny*)CTestSession::ETestDeadServer);
       
   684 		clientInfo.SetPaging(TThreadCreateInfo::EPaged);
       
   685 		clientInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize);
       
   686 		RThread clientThread;
       
   687 		test_KErrNone(clientThread.Create(clientInfo));
       
   688 		TRequestStatus clientStat;
       
   689 		clientThread.Logon(clientStat);
       
   690 		clientThread.Resume();
       
   691 		gSem.Wait();
       
   692 		
       
   693 		// Signal to stop ActiveScheduler and wait for server to stop.
       
   694 		session.PublicSendReceive(CTestSession::EStop, TIpcArgs());
       
   695 		session.Close();
       
   696 		User::WaitForRequest(serverStat);
       
   697 		if (serverThread.ExitType() != EExitKill)
       
   698 			{
       
   699 			test.Printf(_L("!!Server thread did something bizarre %d"), serverThread.ExitReason());
       
   700 			}
       
   701 
       
   702 		gSem1.Signal();
       
   703 		User::WaitForRequest(clientStat);
       
   704 		test_Equal(EExitKill, clientThread.ExitType());
       
   705 		test_Equal(KErrServerTerminated, clientThread.ExitReason());
       
   706 
       
   707 		CLOSE_AND_WAIT(clientThread);
       
   708 		CLOSE_AND_WAIT(serverThread);
       
   709 		CLOSE_AND_WAIT(gSem);
       
   710 		CLOSE_AND_WAIT(gSem1);
       
   711 		}
       
   712 	test(!exitFailure);
       
   713 
       
   714 	test.Next(_L("Test server setting pinning policy after server started"));
       
   715 	RThread serverThread;
       
   716 	test_KErrNone(serverThread.Create(_L("Server Thread"),ServerThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize, (TAny*)gServerPinningState));
       
   717 	TRequestStatus serverStat;
       
   718 	serverThread.Logon(serverStat);
       
   719 	serverThread.Resume();
       
   720 	// The server should have panicked with E32USER-CBase 106.
       
   721 	User::WaitForRequest(serverStat);
       
   722 	TInt exitReason = serverThread.ExitReason();
       
   723 	TInt exitType = serverThread.ExitType();
       
   724 	test_Equal(EExitPanic, exitType);
       
   725 	test_Equal(ECServer2InvalidSetPin, exitReason);
       
   726 	if (_L("E32USER-CBase") != serverThread.ExitCategory())
       
   727 		test(0);
       
   728 	CLOSE_AND_WAIT(serverThread);
       
   729 
       
   730 	test.End();
       
   731 
       
   732 	// Set JIT back to original state.
       
   733 	User::SetJustInTime(justInTime);
       
   734 
       
   735 	return (KErrNone);
       
   736 	}