os/kernelhwsrv/kerneltest/e32test/bench/t_svr.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-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\bench\t_svr.cpp
    15 // Overview:
    16 // Tests and benchmarks the Client/Server architecture of the Symbian platform.
    17 // The client and server run in different threads in the same process. 
    18 // API Information:
    19 // CSession2, CServer2, RSessionBase.
    20 // Details:
    21 // - Create and start a server thread. Verify results are as expected.
    22 // - Open a connection with the server, verify arguments are passed to the server
    23 // and back correctly.
    24 // - Server can read and write messages to/from the client and return verify that 
    25 // the results are as expected.
    26 // - Send dummy messages that the server completes immediately and display how many 
    27 // are completed per second.
    28 // - Stop the server and verify the results are as expected.
    29 // - Verify that the kernel does not crash by completing a message with an invalid 
    30 // handle and verify the client is panicked with EBadMessageHandle.
    31 // Platforms/Drives/Compatibility:
    32 // All.
    33 // Assumptions/Requirement/Pre-requisites:
    34 // Failures and causes:
    35 // Base Port information:
    36 // 
    37 //
    38 
    39 #define __E32TEST_EXTENSION__
    40 
    41 #include <e32base.h>
    42 #include <e32base_private.h>
    43 #include <e32test.h>
    44 #include <e32svr.h>
    45 #include <hal.h>
    46 #include <e32math.h>
    47 
    48 #include "../mmu/mmudetect.h"
    49 
    50 const TInt KHeapSize=0x2000;
    51 const TInt KMajorVersionNumber=1;
    52 const TInt KMinorVersionNumber=0;
    53 const TInt KBuildVersionNumber=1;
    54 
    55 _LIT(KServerName,"Display");
    56 
    57 _LIT(KReadDesContents, "Testing read");
    58 _LIT(KLengthDesContents, "What-ever");
    59 _LIT(KWriteDesContents, "It worked!");
    60 _LIT(KLocalWriteDesContents, "Local write");
    61 
    62 enum TSpeedTest
    63 	{
    64 	ESpeedNull,
    65 	ESpeedUnusedDes,
    66 	ESpeedGetDesLength,
    67 	ESpeedGetMaxDesLength,
    68 	ESpeedReadDes,
    69 	ESpeedWriteDes,
    70 	};
    71 
    72 _LIT(KTestNameNull,            "Null");
    73 _LIT(KTestNameUnusedDes,       "UnusedDes");
    74 _LIT(KTestNameGetDesLength,    "GetDesLength");
    75 _LIT(KTestNameGetMaxDesLength, "GetMaxDesLength");
    76 _LIT(KTestNameReadDes,         "ReadDes");
    77 _LIT(KTestNameWriteDes,        "WriteDes");
    78 
    79 _LIT(KLitLocal, 			   "Local");
    80 _LIT(KLitRemote, 			   "Remote");
    81 
    82 const TDesC* KSpeedTestNames[] =
    83 	{
    84 	&KTestNameNull,
    85 	&KTestNameUnusedDes,
    86 	&KTestNameGetDesLength,
    87 	&KTestNameGetMaxDesLength,
    88 	&KTestNameReadDes,
    89 	&KTestNameWriteDes,
    90 	};
    91 
    92 class CMySession : public CSession2
    93 	{
    94 public:
    95 	CMySession();
    96 	~CMySession();
    97 	void DisplayName(const RMessage2& aM);
    98 	virtual void ServiceL(const RMessage2& aMessage);		 	 //pure virtual fns.
    99 private:
   100 	RArray<RMessagePtr2> iAsyncRequests;
   101 	};
   102 
   103 class CMyServer : public CServer2
   104 	{
   105 public:
   106 	enum {EDisplay,ERead,EGetDesLength,EGetDesMaxLength,EWrite,ELocalWrite,EDupDes,ENull,ESimpleRead,ESimpleWrite,EStartAsync,ECompleteAsync,EStop};
   107 public:
   108 	CMyServer(TInt aPriority);
   109 	static CMyServer* New(TInt aPriority);
   110 	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;//Overloading
   111 	};
   112 
   113 class CMyActiveScheduler : public CActiveScheduler
   114 	{
   115 public:
   116 	virtual void Error(TInt anError) const;	 //Overloading pure virtual function
   117 	};
   118 
   119 class RDisplay : public RSessionBase
   120 	{
   121 public:
   122 	TInt Open(TInt aMessageSlots=0);
   123 	TInt Display(const TDesC& aMessage);
   124 	TInt Read(TInt aArgIndex);
   125 	TInt Write(TInt aArgIndex);
   126 	TInt LocalWrite(TInt aArgIndex);
   127 	TInt TestDesLength(TInt aArgIndex);
   128 	TInt Stop();
   129 	TInt SpeedTest(TSpeedTest);
   130 	TInt Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3);
   131 	void StartAsync(TRequestStatus& aStatus);
   132 	void CompleteAsync(TInt aIndex);
   133 	TInt SendBlind();
   134 	TVersion Version();
   135 private:
   136 	TInt SendMessage(TInt aMessage, TInt aArgIndex, TDesC* aDesArg, TInt8 aOffset = 0);
   137 	TInt SendMessage(TInt aMessage, TInt aArgIndex, TDes* aDesArg, TInt8 aOffset = 0);
   138 	TInt SendMessageDup(TInt aMessage, TInt aArgIndex, TInt aArgIndex2, TDes* aDesArgs);
   139 	};
   140 
   141 LOCAL_D RTest test(_L("T_SVR"));
   142 LOCAL_D RTest testSvr(_L("T_SVR Server"));
   143 LOCAL_D RTest testSpeedy(_L("T_SVR Speedy"));
   144 LOCAL_D TRequestStatus speedTestStatus;
   145 LOCAL_D RThread serverThread;
   146 LOCAL_D RProcess serverProcess;
   147 
   148 //
   149 // Constructor
   150 // 
   151 CMySession::CMySession()
   152 	{}
   153 
   154 //
   155 // Destructor
   156 // 
   157 CMySession::~CMySession()
   158 	{
   159 	// Call User::Exit so server shuts down when client disconnects
   160 	User::Exit(KErrNone);
   161 	}
   162 
   163 void CMySession::DisplayName(const RMessage2& aM)
   164 //
   165 // Display the client's name.
   166 //
   167 	{
   168 
   169 	RThread t;
   170 	TInt r = aM.Client(t);
   171 	testSvr(r==KErrNone);
   172 	TFullName fn(t.FullName());
   173 	t.Close();
   174 	TBuf<256> text;
   175 	r=aM.Read(0,text);
   176 	testSvr(r==KErrNone);
   177 	testSvr.Printf(_L("Session %S\n%S\n"), &fn, &text);
   178 	}
   179 
   180 CMyServer* CMyServer::New(TInt aPriority)
   181 //
   182 // Create a new CMyServer.
   183 //
   184 	{
   185 
   186 	return new CMyServer(aPriority);
   187 	}
   188 
   189 CMyServer::CMyServer(TInt aPriority)
   190 //
   191 // Constructor.
   192 //
   193 	: CServer2(aPriority)
   194 	{}
   195 
   196 CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
   197 //
   198 // Create a new client for this server.
   199 //
   200 	{
   201 
   202 	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
   203 	if (!User::QueryVersionSupported(v,aVersion))
   204 		User::Leave(KErrNotSupported);
   205 	return(new(ELeave) CMySession());
   206 	}
   207 
   208 void CMySession::ServiceL(const RMessage2& aMessage)
   209 //
   210 // Handle messages for this server.
   211 //
   212 	{
   213 
   214 	TInt f = aMessage.Function();
   215 	if (f & 0x40000000)
   216 		{
   217 		TInt what = f & 0x3fffffff;
   218 		TInt a0 = aMessage.Int0();
   219 		TInt a1 = aMessage.Int1();
   220 		TInt a2 = aMessage.Int2();
   221 		TInt a3 = aMessage.Int3();
   222 		switch (what)
   223 			{
   224 			case 0:
   225 				aMessage.Complete(a0);
   226 				return;
   227 			case 1:
   228 				aMessage.Complete(a1);
   229 				return;
   230 			case 2:
   231 				aMessage.Complete(a2);
   232 				return;
   233 			case 3:
   234 				aMessage.Complete(a3);
   235 				return;
   236 			case 4:
   237 				aMessage.Complete(a0+a1+a2+a3);
   238 				return;
   239 			case 5:
   240 				aMessage.Complete(a0*a0+a1*a1+a2*a2+a3*a3);
   241 				return;
   242 			default:
   243 				break;
   244 			}
   245 		}
   246 
   247 	TInt r=KErrNone;
   248 	TBuf<0x10> b;
   249 	TDes* des = NULL;
   250 
   251 	TInt message = f & 0xff;
   252 	TInt arg = (f >> 8) & 0xff;
   253 	TInt8 offset = (TInt8)((f >> 16) & 0xff);
   254 
   255 	switch (message)
   256 		{
   257 	case CMyServer::EDisplay:
   258 		DisplayName(aMessage);
   259 		break;
   260 	case CMyServer::ERead:
   261 		r=aMessage.Read(arg,b,offset);
   262 		if (r==KErrNone && b!=KReadDesContents)
   263 			r=KErrGeneral;
   264 		break;
   265 	case CMyServer::EGetDesLength:
   266 		r=aMessage.GetDesLength(arg);
   267 		break;
   268 	case CMyServer::EGetDesMaxLength:
   269 		r=aMessage.GetDesMaxLength(arg);
   270 		break;
   271 	case CMyServer::EWrite:
   272 		r=aMessage.Write(arg,KWriteDesContents,offset);
   273 		// Test descriptor length updated
   274 		if (r == KErrNone && aMessage.GetDesLength(arg) != 10)
   275 			r = KErrGeneral;
   276 		// Test reading descriptor back again
   277 		if (r == KErrNone)
   278 			r = aMessage.Read(arg,b,offset);
   279 		if (r==KErrNone && b!=KWriteDesContents)
   280 			r = KErrGeneral;
   281 		break;
   282 	case CMyServer::ELocalWrite:
   283 		switch(arg)
   284 			{
   285 			case 0:
   286 				des = (TDes*)aMessage.Int0();
   287 				break;
   288 			case 1:
   289 				des = (TDes*)aMessage.Int1();
   290 				break;
   291 			case 2:
   292 				des = (TDes*)aMessage.Int2();
   293 				break;
   294 			case 3:
   295 				des = (TDes*)aMessage.Int3();
   296 				break;
   297 			default:
   298 				r = KErrGeneral;
   299 			}
   300 		if (r==KErrNone)
   301 			{
   302 			*des = KLocalWriteDesContents;
   303 			r = aMessage.GetDesLength(arg) == 11 ? KErrNone : KErrGeneral;
   304 			}
   305 		if (r==KErrNone)
   306 			r=aMessage.Read(arg,b,0);
   307 		if (r==KErrNone && b!=KLocalWriteDesContents)
   308 			r=KErrGeneral;
   309 		break;
   310 	case CMyServer::EDupDes:
   311 		r=aMessage.Write(arg,KWriteDesContents);
   312 		if (r == KErrNone && aMessage.GetDesLength(offset/* used to pass 2nd arg here*/) != 10)
   313 			r = KErrGeneral;
   314 		if (r == KErrNone)
   315 			r = aMessage.Read(offset,b);
   316 		if (r==KErrNone && b!=KWriteDesContents)
   317 			r = KErrGeneral;
   318 		break;
   319 	case CMyServer::ENull:
   320 		break;
   321 	case CMyServer::ESimpleRead:
   322 		r=aMessage.Read(arg,b);
   323 		break;
   324 	case CMyServer::ESimpleWrite:
   325 		r=aMessage.Write(arg,KWriteDesContents);
   326 		break;
   327 	case CMyServer::EStartAsync:
   328 		r=iAsyncRequests.Append(aMessage);
   329 		if (r == KErrNone)
   330 			return;  // don't complete message
   331 		break;
   332 	case CMyServer::ECompleteAsync:
   333 		{
   334 		TInt index = aMessage.Int0();
   335 		if (iAsyncRequests.Count() <= index)
   336 			r = KErrNotFound;
   337 		else
   338 			{
   339 			RMessagePtr2 asyncMessage = iAsyncRequests[index];
   340 			iAsyncRequests.Remove(index);
   341 			asyncMessage.Complete(KErrNone);
   342 			r=KErrNone;
   343 			}
   344 		}
   345 		break;
   346 	case CMyServer::EStop:
   347 		CActiveScheduler::Stop();
   348 		break;
   349 	default:
   350 		r=KErrNotSupported;
   351 		}
   352 	aMessage.Complete(r);
   353 	}
   354 
   355 void CMyActiveScheduler::Error(TInt anError) const
   356 //
   357 // Called if any Run() method leaves.
   358 //
   359 	{
   360 
   361 	testSvr.Panic(anError,_L("CMyActiveScheduler::Error"));
   362 	}
   363 
   364 TInt RDisplay::Open(TInt aMessageSlots)
   365 //
   366 // Open the server.
   367 //
   368 	{
   369 
   370 	return(CreateSession(KServerName,Version(),aMessageSlots));
   371 	}
   372 
   373 TInt RDisplay::Display(const TDesC& aMessage)
   374 //
   375 // Display a message.
   376 //
   377 	{
   378 
   379 	TBuf<0x10> b(aMessage);
   380 	return(SendReceive(CMyServer::EDisplay,TIpcArgs(&b)));
   381 	}
   382 
   383 TInt RDisplay::SendMessage(TInt aMessage, TInt aArgIndex, TDesC* aDesArg, TInt8 aOffset)
   384 	{
   385 	TInt f = aMessage | (aArgIndex << 8) | ((aOffset << 16) & 0x00ff0000);
   386 	TIpcArgs args;
   387 	args.Set(aArgIndex, aDesArg);
   388 	return SendReceive(f, args);
   389 	}
   390 
   391 TInt RDisplay::SendMessage(TInt aMessage, TInt aArgIndex, TDes* aDesArg, TInt8 aOffset)
   392 	{
   393 	TInt f = aMessage | (aArgIndex << 8) | ((aOffset << 16) & 0x00ff0000);
   394 	TIpcArgs args;
   395 	args.Set(aArgIndex, aDesArg);
   396 	return SendReceive(f, args);
   397 	}
   398 
   399 TInt RDisplay::SendMessageDup(TInt aMessage, TInt aArgIndex1, TInt aArgIndex2, TDes* aDesArg)
   400 	{
   401 	TInt f = aMessage | (aArgIndex1 << 8) | (aArgIndex2 << 16);
   402 	TIpcArgs args;
   403 	args.Set(aArgIndex1, aDesArg);
   404 	args.Set(aArgIndex2, aDesArg);
   405 	return SendReceive(f, args);
   406 	}
   407 
   408 TInt RDisplay::Read(TInt aArgIndex)
   409 //
   410 // Test RMessage2::Read
   411 //
   412 	{
   413 	HBufC* buf = HBufC::New(0x10);
   414 	test_NotNull(buf);
   415 	*buf = KReadDesContents;
   416 
   417 	TBufC<0x10> des1(KReadDesContents);
   418 	TBuf<0x10> des2(KReadDesContents);
   419 	TPtrC des3(des1);
   420 	TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
   421 	RBuf des5(buf);
   422 	
   423 	// test successful read
   424 	test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des1));
   425 	test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des2));
   426 	test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des3));
   427 	test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des4));
   428 	test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des5));
   429 
   430 	// test negative offset
   431 	test_Equal(KErrArgument, SendMessage(CMyServer::ERead, aArgIndex, &des1, -1));
   432 
   433 	// test bad descriptors
   434 	if (HaveVirtMem())
   435 		{
   436 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, (TDesC*)0x30000000));
   437 
   438 		RChunk chunk;
   439 		const TInt KChunkSize = 4096;
   440 		test_KErrNone(chunk.CreateLocal(KChunkSize, KChunkSize));
   441 		test_Equal(KChunkSize, chunk.Size());
   442 
   443 		TDesC* ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
   444 		Mem::Copy(ptr, &des3, 8);
   445 		test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, ptr));
   446 		
   447 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
   448 		Mem::Copy(ptr, &des3, 4);
   449 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
   450 		
   451 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 12);
   452 		Mem::Copy(ptr, &des4, 12);
   453 		test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, ptr));
   454 		
   455 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
   456 		Mem::Copy(ptr, &des4, 8);
   457 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
   458 		
   459 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
   460 		Mem::Copy(ptr, &des4, 4);
   461 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
   462 		
   463 		chunk.Close();
   464 		
   465 		((TUint32*)&des3)[1] = 0x00001000; // make descriptor point to invalid memory
   466 		((TUint32*)&des4)[2] = 0x00001000; // make descriptor point to invalid memory
   467 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, &des3));
   468 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, &des4));
   469 		}
   470 
   471 	delete buf;
   472 	return KErrNone;
   473 	}
   474 
   475 TInt RDisplay::TestDesLength(TInt aArgIndex)
   476 //
   477 // Test RMessage2::GetDesLength and RMessage2::GetDesMaxLength
   478 //
   479 	{
   480 	HBufC* buf = HBufC::New(0x10);
   481 	test_NotNull(buf);
   482 	*buf = KLengthDesContents;
   483 
   484 	TBufC<0x10> des1(KLengthDesContents);
   485 	TBuf<0x10> des2(KLengthDesContents);
   486 	TPtrC des3(des1);
   487 	TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
   488 	RBuf des5(buf);
   489 	
   490 	// test GetDesLength
   491 	test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des1));
   492 	test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des2));
   493 	test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des3));
   494 	test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des4));
   495 	test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des5));
   496 
   497 	// test GetDesMaxLength
   498 	test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des1));
   499 	test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des2));
   500 	test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des3));
   501 	test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des4));
   502 	test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des5));
   503 
   504 	// test bad descriptors
   505 	if (HaveVirtMem())
   506 		{
   507 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, (TDesC*)0x30000000));
   508 
   509 		RChunk chunk;
   510 		const TInt KChunkSize = 4096;
   511 		test_KErrNone(chunk.CreateLocal(KChunkSize, KChunkSize));
   512 		test_Equal(KChunkSize, chunk.Size());
   513 
   514 		TDesC* ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
   515 		Mem::Copy(ptr, &des3, 8);
   516 		test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
   517 		
   518 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
   519 		Mem::Copy(ptr, &des3, 4);
   520 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
   521 		
   522 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 12);
   523 		Mem::Copy(ptr, &des4, 12);
   524 		test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
   525 		test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
   526 		
   527 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
   528 		Mem::Copy(ptr, &des4, 8);
   529 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
   530 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
   531 		
   532 		ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
   533 		Mem::Copy(ptr, &des4, 4);
   534 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
   535 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
   536 		
   537 		chunk.Close();
   538 		}
   539 
   540 	delete buf;
   541 	return KErrNone;
   542 	}
   543 
   544 TInt RDisplay::Write(TInt aArgIndex)
   545 //
   546 // Get session to test CSession2::WriteL.
   547 //
   548 	{
   549 	HBufC* buf = HBufC::New(0x10);
   550 	test_NotNull(buf);
   551 
   552 	TBufC<0x10> des1;
   553 	TBuf<0x10> des2;
   554 	TPtrC des3(des1);
   555 	TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
   556 	RBuf des5(buf);
   557 
   558 	// test successful write
   559 	test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des2));
   560 	test(des2 == KWriteDesContents);	
   561 	test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des4));
   562 	test(des4 == KWriteDesContents);	
   563 	test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des5));
   564 	test(des5 == KWriteDesContents);
   565 	test(*buf == KWriteDesContents);
   566 
   567 	// test buffer too short
   568 	TBuf<1> small;
   569 	test_Equal(KErrOverflow, SendMessage(CMyServer::EWrite, aArgIndex, &small));
   570 
   571 	// test write to constant descriptors
   572 	test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des1));
   573 	test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des3));
   574 
   575 	// test negative offset
   576 	test_Equal(KErrArgument, SendMessage(CMyServer::EWrite, aArgIndex, &des2, -1));
   577 
   578 	// test multiple instances of same descriptor
   579 	for (TInt i = 0 ; i < 4 ; ++i)
   580 		{
   581 		if (i != aArgIndex)
   582 			{
   583 			des2.Zero();
   584 			test_Equal(KErrNone, SendMessageDup(CMyServer::EDupDes, aArgIndex, i, &des2));
   585 			test(des2 == KWriteDesContents);
   586 			}
   587 		}
   588 
   589 	// test bad descriptors - do this last as it corrupts the descriptors.
   590 	if (HaveVirtMem())
   591 		{
   592 		((TUint32*)&des3)[1] = 0x00001000; // make descriptor point to invalid memory
   593 		((TUint32*)&des4)[2] = 0x00001000; // make descriptor point to invalid memory
   594 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des3));
   595 		test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des4));
   596 		}
   597 
   598 	delete buf;
   599 	return KErrNone;
   600 	}
   601 
   602 TInt RDisplay::LocalWrite(TInt aArgIndex)
   603 	{
   604 	// test local write to descriptor
   605 	TBuf<0x10> des2;
   606 	des2.Zero();
   607 	test_Equal(KErrNone, SendMessage(CMyServer::ELocalWrite, aArgIndex, &des2));
   608 	test(des2 == KLocalWriteDesContents);
   609 	return KErrNone;
   610 	}
   611 
   612 void RDisplay::StartAsync(TRequestStatus& aStatus)
   613 	{
   614 	SendReceive(CMyServer::EStartAsync, TIpcArgs(), aStatus);
   615 	}
   616 
   617 void RDisplay::CompleteAsync(TInt aIndex)
   618 	{
   619 	test_KErrNone(SendReceive(CMyServer::ECompleteAsync, TIpcArgs(aIndex)));
   620 	}
   621 
   622 TInt RDisplay::SendBlind()
   623 	{
   624 	return Send(CMyServer::EStartAsync);
   625 	}
   626 
   627 TInt RDisplay::SpeedTest(TSpeedTest aTest)
   628 	{
   629 	TBuf<0x10> des(KReadDesContents);
   630 	
   631 	TInt count = 0;
   632 	TInt r = KErrNone;
   633 	switch (aTest)
   634 		{
   635 		case ESpeedNull:
   636 			while (speedTestStatus == KRequestPending)
   637 				{
   638 				r = SendReceive(CMyServer::ENull, TIpcArgs());
   639 				count++;
   640 				}
   641 			r = (r == KErrNone) ? count : KErrGeneral;
   642 			break;
   643 			
   644 		case ESpeedUnusedDes:
   645 			while (speedTestStatus == KRequestPending)
   646 				{
   647 				r = SendReceive(CMyServer::ENull, TIpcArgs(&des));
   648 				count++;
   649 				}
   650 			r = (r == KErrNone) ? count : KErrGeneral;
   651 			break;
   652 			
   653 		case ESpeedGetDesLength:
   654 			while (speedTestStatus == KRequestPending)
   655 				{
   656 				r = SendReceive(CMyServer::EGetDesLength, TIpcArgs(&des));
   657 				count++;
   658 				}
   659 			r = (r == 12) ? count : KErrGeneral;
   660 			break;
   661 			
   662 		case ESpeedGetMaxDesLength:
   663 			while (speedTestStatus == KRequestPending)
   664 				{
   665 				r = SendReceive(CMyServer::EGetDesMaxLength, TIpcArgs(&des));
   666 				count++;
   667 				}
   668 			r = (r == 0x10) ? count : KErrGeneral;
   669 			break;
   670 			
   671 		case ESpeedReadDes:
   672 			while (speedTestStatus == KRequestPending)
   673 				{
   674 				r = SendReceive(CMyServer::ESimpleRead, TIpcArgs(&des));
   675 				count++;
   676 				}
   677 			r = (r == KErrNone) ? count : KErrGeneral;
   678 			break;
   679 			
   680 		case ESpeedWriteDes:
   681 			while (speedTestStatus == KRequestPending)
   682 				{
   683 				r = SendReceive(CMyServer::ESimpleWrite, TIpcArgs(&des));
   684 				count++;
   685 				}
   686 			r = (r == KErrNone) ? count : KErrGeneral;
   687 			break;
   688 			
   689 		default:
   690 			r = KErrArgument;
   691 		}
   692 	return r;
   693 	}
   694 
   695 TInt RDisplay::Stop()
   696 //
   697 // Stop the server.
   698 //
   699 	{
   700 
   701 	return SendReceive(CMyServer::EStop, TIpcArgs());
   702 	}
   703 
   704 TVersion RDisplay::Version()
   705 //
   706 // Return the current version.
   707 //
   708 	{
   709 
   710 	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
   711 	return v;
   712 	}
   713 
   714 TInt RDisplay::Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3)
   715 	{
   716 	return SendReceive(0x40000000|aWhat, TIpcArgs(a0,a1,a2,a3));
   717 	}
   718 
   719 LOCAL_C TInt serverThreadEntryPoint(TAny*)
   720 //
   721 // The entry point for the producer thread.
   722 //
   723 	{
   724 	RThread().SetPriority(EPriorityMore);
   725 
   726 	CMyActiveScheduler* pR=new CMyActiveScheduler;
   727 	testSvr(pR!=NULL);
   728 	CActiveScheduler::Install(pR);
   729 	
   730 	CMyServer* pS=CMyServer::New(0);
   731 	testSvr(pS!=NULL);
   732 	
   733 	TInt r=pS->Start(KServerName);
   734 	testSvr(r==KErrNone);
   735 	
   736 	RThread::Rendezvous(KErrNone);
   737 	RProcess::Rendezvous(KErrNone);
   738 	
   739 	CActiveScheduler::Start();
   740 	
   741 	delete pS;
   742 	testSvr.Close();
   743 	return(KErrNone);
   744 	}
   745 
   746 LOCAL_C TInt RunPanicThread(RThread& aThread)
   747 	{
   748 	TRequestStatus s;
   749 	aThread.Logon(s);
   750 	TBool jit = User::JustInTime();
   751 	User::SetJustInTime(EFalse);
   752 	aThread.Resume();
   753 	User::WaitForRequest(s);
   754 	User::SetJustInTime(jit);
   755 	return s.Int();
   756 	}
   757 
   758 LOCAL_C TInt RogueThread1(TAny*)
   759 	{
   760 	// try to kill the kernel
   761 	RMutex mutex;
   762 	TPtrC* p=(TPtrC*)0x00001000; // make descriptor point to invalid memory
   763 	mutex.CreateGlobal(*p,EOwnerProcess);	// this should panic the thread
   764 	return KErrNone;
   765 	}
   766 
   767 class RMessageT : public RMessage2
   768 	{
   769 public:
   770 	RMessageT(TLinAddr anAddr) { iFunction=0; iHandle=(TInt)anAddr; }
   771 	};
   772 
   773 LOCAL_C TInt RogueThread2(TAny*)
   774 	{
   775 	// try to kill the kernel
   776 	RMessageT m(0x30000000);
   777 	m.Complete(KErrNone);					// this should panic the thread
   778 	return KErrNone;
   779 	}
   780 
   781 LOCAL_C TInt RogueThread3(TAny*)
   782 	{
   783 	// try to kill the kernel
   784 	RMessageT m(0x80000000);
   785 	m.Complete(KErrNone);					// this should panic the thread
   786 	return KErrNone;
   787 	}
   788 
   789 LOCAL_C TInt RogueThread4(TAny*)
   790 	{
   791 	// try to kill the kernel
   792 	RMessageT m(0x800fff00);				// this should be off the end of the kernel heap
   793 	m.Complete(KErrNone);					// this should panic the thread
   794 	return KErrNone;
   795 	}
   796 
   797 LOCAL_C void DisplayThreadExitInfo(const RThread& aThread)
   798 	{
   799 	TFullName fn=aThread.FullName();
   800 	TExitType exitType=aThread.ExitType();
   801 	TInt exitReason=aThread.ExitReason();
   802 	TBuf<32> exitCat=aThread.ExitCategory();
   803 	test.Printf(_L("Thread %S exited %d,%d,%S\n"),&fn,exitType,exitReason,&exitCat);
   804 	}
   805 
   806 LOCAL_C void RogueThreadTest()
   807 	{
   808 	test.Start(_L("Rogue thread tests"));
   809 	
   810 	RThread thread;
   811 	TInt r;
   812 	if (HaveVirtMem())
   813 		{
   814 		test.Next(_L("Rogue thread test 1"));
   815 		r=thread.Create(_L("Rogue1"),RogueThread1,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   816 		test(r==KErrNone);
   817 		RunPanicThread(thread);
   818 		DisplayThreadExitInfo(thread);
   819 		test(thread.ExitType()==EExitPanic);
   820 		test(thread.ExitReason()==ECausedException);
   821 		CLOSE_AND_WAIT(thread);
   822 		}
   823 
   824 	test.Next(_L("Rogue thread test 2"));
   825 	r=thread.Create(_L("Rogue2"),RogueThread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   826 	test(r==KErrNone);
   827 	RunPanicThread(thread);
   828 	DisplayThreadExitInfo(thread);
   829 	test(thread.ExitType()==EExitPanic);
   830 	test(thread.ExitReason()==EBadMessageHandle);
   831 	CLOSE_AND_WAIT(thread);
   832 
   833 	test.Next(_L("Rogue thread test 3"));
   834 	r=thread.Create(_L("Rogue3"),RogueThread3,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   835 	test(r==KErrNone);
   836 	RunPanicThread(thread);
   837 	DisplayThreadExitInfo(thread);
   838 	test(thread.ExitType()==EExitPanic);
   839 	test(thread.ExitReason()==EBadMessageHandle);
   840 	CLOSE_AND_WAIT(thread);
   841 
   842 	test.Next(_L("Rogue thread test 4"));
   843 	r=thread.Create(_L("Rogue4"),RogueThread4,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   844 	test(r==KErrNone);
   845 	RunPanicThread(thread);
   846 	DisplayThreadExitInfo(thread);
   847 	test(thread.ExitType()==EExitPanic);
   848 	test(thread.ExitReason()==EBadMessageHandle);
   849 	CLOSE_AND_WAIT(thread);
   850 	test.End();
   851 	}
   852 
   853 class RMySession : public RSessionBase
   854 	{
   855 public:
   856 	TInt Connect(RServer2 aSrv,TRequestStatus& aStat)
   857 		{return CreateSession(aSrv,TVersion(),1,EIpcSession_Unsharable,0,&aStat);}
   858 	void SendTestMessage(TRequestStatus& aStat)
   859 		{SendReceive(0,TIpcArgs(1,2,3,4), aStat);}
   860 	};
   861 
   862 TInt BadServerThread(TAny*)
   863 	{
   864 	RServer2 srv;
   865 	RMySession sess;
   866 	TRequestStatus stat;
   867 	RMessage2 msg;
   868 	RMessage2* badMsg = 0;
   869 	TInt r;
   870 	
   871 	// Test receiving connect message to bad address
   872 	
   873 	r = srv.CreateGlobal(KNullDesC);
   874 	if (r != KErrNone)
   875 		return r;
   876 	r = sess.Connect(srv,stat);
   877 	if (r != KErrNone)
   878 		return r;
   879 	srv.Receive(*badMsg);
   880 	srv.Close();
   881 	User::WaitForRequest(stat);
   882 	if (stat != KErrServerTerminated)
   883 		return KErrGeneral;
   884 	sess.Close();
   885 
   886 	// Test receiving normal message to bad address
   887 	
   888 	r = srv.CreateGlobal(KNullDesC);
   889 	if (r != KErrNone)
   890 		return r;
   891 	r = sess.Connect(srv,stat);
   892 	if (r != KErrNone)
   893 		return r;
   894 	srv.Receive(msg);
   895 	msg.Complete(KErrNone);
   896 	User::WaitForRequest(stat);
   897 	if (stat != KErrNone)
   898 		return KErrGeneral;
   899 	sess.SendTestMessage(stat);
   900 	srv.Receive(*badMsg);
   901 	srv.Close();
   902 	User::WaitForRequest(stat);
   903 	if (stat != KErrServerTerminated)
   904 		return KErrGeneral;
   905 	sess.Close();
   906 
   907 	return 23;
   908 	}
   909 
   910 void BadServerTest()
   911 	{
   912 	// This tests the current behaviour of RServer2::Receive when passed a dodgy RMessage2 pointer,
   913 	// which is to ingore exceptions and not panic the server thread.
   914 
   915 	RThread thread;
   916 	TInt r=thread.Create(_L("BadServer"),BadServerThread,KDefaultStackSize,NULL,NULL);
   917 	test(r==KErrNone);
   918 	TRequestStatus status;
   919 	thread.Logon(status);
   920 	thread.Resume();
   921 	User::WaitForRequest(status);
   922 	test(thread.ExitType()==EExitKill);
   923 	test(thread.ExitReason()==23);
   924 	CLOSE_AND_WAIT(thread);
   925 	}
   926 
   927 void StartServerThread()
   928 	{
   929 	TInt r=serverThread.Create(_L("Server"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   930 	test(r==KErrNone);
   931 	
   932 	TRequestStatus status;
   933 	serverThread.Rendezvous(status);
   934 	serverThread.Resume();
   935 	
   936 	User::WaitForRequest(status);
   937 	test(status == KErrNone);
   938 	}
   939 
   940 void WaitServerThreadDeath()
   941 	{
   942 	TRequestStatus status;
   943 	serverThread.Logon(status);
   944 	User::WaitForRequest(status);
   945 	test(status == KErrNone);
   946 	test(serverThread.ExitReason() == EExitKill);
   947 	CLOSE_AND_WAIT(serverThread);
   948 	}
   949 
   950 void StartServerProcess()
   951 	{
   952 	TInt r=serverProcess.Create(_L("t_svr"),_L("slave"));
   953 	test(r==KErrNone);
   954 
   955 	TRequestStatus status;
   956 	serverProcess.Rendezvous(status);
   957 	serverProcess.Resume();
   958 
   959 	User::WaitForRequest(status);
   960 	test(status == KErrNone);
   961 	}
   962 
   963 void WaitServerProcessDeath()
   964 	{
   965 	TRequestStatus status;
   966 	serverProcess.Logon(status);
   967 	User::WaitForRequest(status);
   968 	test(status == KErrNone);
   969 	test(serverProcess.ExitReason() == EExitKill);
   970 	CLOSE_AND_WAIT(serverProcess);
   971 	}
   972 
   973 void RunSpeedTest(RDisplay& aSess, TBool aLocal, TSpeedTest aTest)
   974 	{
   975     User::After(300000);
   976 
   977 	RTimer timer;
   978 	test(timer.CreateLocal() == KErrNone);
   979 	
   980     timer.After(speedTestStatus, 300000);
   981 	TInt r = aSess.SpeedTest(aTest);
   982 	User::WaitForRequest(speedTestStatus);
   983 	test(r > KErrNone);
   984 
   985     timer.After(speedTestStatus, 3000000);
   986 	TUint startCount = User::FastCounter();
   987 	r = aSess.SpeedTest(aTest);
   988 	TUint endCount = User::FastCounter();
   989 	User::WaitForRequest(speedTestStatus);
   990 	test(r > KErrNone);
   991 
   992 	timer.Close();
   993 
   994 	const TDesC* loc = aLocal ? &KLitLocal : &KLitRemote;
   995 	const TDesC* name = KSpeedTestNames[aTest];
   996 	
   997 	TInt countFreq = 0;
   998 	test(HAL::Get(HAL::EFastCounterFrequency, countFreq) == KErrNone);
   999 
  1000 	TBool fcCountsUp = 0;
  1001 	test(HAL::Get(HAL::EFastCounterCountsUp, fcCountsUp) == KErrNone);
  1002 
  1003 	TInt countDiff = fcCountsUp ? (endCount - startCount) : (startCount - endCount);
  1004 	TReal elapsedTimeUs = (1000000.0 * countDiff) / countFreq;
  1005 	TReal time = elapsedTimeUs / r;
  1006 	
  1007     test.Printf(_L("%S, %S, %f\n"), loc, name, time);
  1008 	}
  1009 
  1010 void RunAllSpeedTests(TBool aLocal)
  1011 	{
  1012 	RDisplay t;
  1013 	test(t.Open() == KErrNone);
  1014 	
  1015 	RunSpeedTest(t, aLocal, ESpeedNull);
  1016 	RunSpeedTest(t, aLocal, ESpeedUnusedDes);
  1017 	RunSpeedTest(t, aLocal, ESpeedGetDesLength);
  1018 	RunSpeedTest(t, aLocal, ESpeedGetMaxDesLength);
  1019 	RunSpeedTest(t, aLocal, ESpeedReadDes);
  1020 	RunSpeedTest(t, aLocal, ESpeedWriteDes);
  1021 	
  1022 	t.Close();
  1023 	}
  1024 
  1025 const TInt KMaxRequests = 20;
  1026 const TInt KSoakIterations = 1000;
  1027 
  1028 void DoTestMultipleOutstandingRequests(RDisplay t)
  1029 	{
  1030 	TRequestStatus status[KMaxRequests];
  1031 	
  1032 	test.Start(_L("Test multiple async requests\n"));
  1033 	
  1034 	test.Next(_L("Test multiple async requests, complete in order\n"));
  1035 	TInt i;
  1036 	for (i = 0 ; i < KMaxRequests ; ++i)
  1037 		{
  1038 		t.StartAsync(status[i]);
  1039 		test_Equal(KRequestPending, status[i].Int());
  1040 		}
  1041 	for (i = 0 ; i < KMaxRequests ; ++i)
  1042 		{
  1043 		t.CompleteAsync(0);  // complete first remaining async request
  1044 		User::WaitForAnyRequest();
  1045 		test_KErrNone(status[i].Int());
  1046 		}
  1047 
  1048 	test.Next(_L("Test multiple async requests, complete in reverse order\n"));
  1049 	for (i = 0 ; i < KMaxRequests ; ++i)
  1050 		{
  1051 		t.StartAsync(status[i]);
  1052 		test_Equal(KRequestPending, status[i].Int());
  1053 		}
  1054 	for (i = KMaxRequests - 1 ; i >= 0 ; --i)
  1055 		{
  1056 		t.CompleteAsync(i);  // complete last remaining async request
  1057 		User::WaitForAnyRequest();
  1058 		test_KErrNone(status[i].Int());
  1059 		}
  1060 
  1061 	test.Next(_L("Soak test multiple async requests, complete in random order\n"));
  1062 	for (i = 0 ; i < KMaxRequests ; ++i)
  1063 		{
  1064 		t.StartAsync(status[i]);
  1065 		test_Equal(KRequestPending, status[i].Int());
  1066 		}
  1067 	for (TInt j = 0 ; j < KSoakIterations ; ++j)
  1068 		{
  1069 		// complete random async request
  1070 		i = Math::Random() % KMaxRequests;
  1071 		t.CompleteAsync(i);
  1072 		User::WaitForAnyRequest();
  1073 		
  1074 		// find which one got completed
  1075 		for (i = 0 ; i < KMaxRequests ; ++i)
  1076 			if (status[i] != KRequestPending)
  1077 				break;
  1078 		test(i < KMaxRequests);
  1079 		test_KErrNone(status[i].Int());
  1080 		
  1081 		// re-start request
  1082 		t.StartAsync(status[i]);
  1083 		test_Equal(KRequestPending, status[i].Int());
  1084 
  1085 		if (j % 100 == 0)
  1086 			test.Printf(_L("."));
  1087 		}
  1088 	test.Printf(_L("\n"));
  1089 	for (i = 0 ; i < KMaxRequests ; ++i)
  1090 		{
  1091 		t.CompleteAsync(0);
  1092 		User::WaitForAnyRequest();
  1093 		}
  1094 	for (i = 0 ; i < KMaxRequests ; ++i)
  1095 		test_KErrNone(status[i].Int());
  1096 
  1097 	test.End();
  1098 	}
  1099 
  1100 void TestMultipleOutstandingRequests()
  1101 	{
  1102 	TRequestStatus status[2];
  1103 
  1104 	test.Next(_L("Test zero async message slots\n"));
  1105 	RDisplay t;
  1106 	StartServerThread();
  1107 	test_KErrNone(t.Open(0));
  1108 	t.StartAsync(status[0]);
  1109 	User::WaitForAnyRequest();
  1110 	test_Equal(KErrServerBusy, status[0].Int());
  1111 	t.Close();
  1112 	WaitServerThreadDeath();
  1113 
  1114 	test.Next(_L("Test one async request\n"));
  1115 	StartServerThread();
  1116 	test_KErrNone(t.Open(1));
  1117 	t.StartAsync(status[0]);
  1118 	t.StartAsync(status[1]);
  1119 	User::WaitForAnyRequest();
  1120 	test_Equal(KRequestPending, status[0].Int());
  1121 	test_Equal(KErrServerBusy, status[1].Int());
  1122 	User::After(1000);
  1123 	test_Equal(KRequestPending, status[0].Int());
  1124 	t.CompleteAsync(0);
  1125 	User::WaitForAnyRequest();
  1126 	test_KErrNone(status[0].Int());
  1127 
  1128 	test.Next(_L("Test one async request, again\n"));
  1129 	t.StartAsync(status[0]);
  1130 	test_Equal(KRequestPending, status[0].Int());
  1131 	t.CompleteAsync(0);
  1132 	User::WaitForAnyRequest();
  1133 	test_KErrNone(status[0].Int());
  1134 	t.Close();
  1135 	WaitServerThreadDeath();
  1136 
  1137 	test.Next(_L("Test multiple async requests using dedicated message slots\n"));
  1138 	StartServerThread();
  1139 	test_KErrNone(t.Open(KMaxRequests));
  1140 	DoTestMultipleOutstandingRequests(t);
  1141 	t.Close();
  1142 	WaitServerThreadDeath();
  1143 
  1144 	test.Next(_L("Test multiple async requests using global pool\n"));
  1145 	StartServerThread();
  1146 	test_KErrNone(t.Open(-1));
  1147 	DoTestMultipleOutstandingRequests(t);
  1148 	t.Close();
  1149 	WaitServerThreadDeath();	
  1150 	}
  1151 
  1152 void CheckNoOutstandingSignals()
  1153 	{
  1154 	RTimer timer;
  1155 	test_KErrNone(timer.CreateLocal());
  1156 	TRequestStatus status;
  1157 	timer.After(status, 1000);
  1158 	User::WaitForAnyRequest();
  1159 	test_KErrNone(status.Int());
  1160 	timer.Close();
  1161 	}
  1162 
  1163 void TestBlindMessages()
  1164 	{
  1165 	test.Start(_L("Test sending blind messages to server"));
  1166 	CheckNoOutstandingSignals();
  1167 	
  1168 	RDisplay t;
  1169 	StartServerThread();
  1170 	test_KErrNone(t.Open(0));
  1171 	test_Equal(KErrServerBusy, t.SendBlind());
  1172 	t.Close();
  1173 	WaitServerThreadDeath();
  1174 	
  1175 	StartServerThread();
  1176 	test_KErrNone(t.Open(2));
  1177 	test_KErrNone(t.SendBlind());
  1178 	test_KErrNone(t.SendBlind());
  1179 	test_Equal(KErrServerBusy, t.SendBlind());
  1180 	t.CompleteAsync(0);
  1181 	test_KErrNone(t.SendBlind());
  1182 	test_Equal(KErrServerBusy, t.SendBlind());
  1183 	t.CompleteAsync(0);
  1184 	t.CompleteAsync(0);
  1185 	test_KErrNone(t.SendBlind());
  1186 	test_KErrNone(t.SendBlind());
  1187 	test_Equal(KErrServerBusy, t.SendBlind());
  1188 	t.CompleteAsync(0);
  1189 	t.CompleteAsync(0);
  1190 	t.Close();
  1191 	WaitServerThreadDeath();
  1192 	
  1193 	CheckNoOutstandingSignals();
  1194 	test.End();
  1195 	}
  1196 
  1197 void RunCommonServerTests(TBool /*aSameProcess*/)
  1198 	{
  1199 	test.Start(_L("Connect to server"));
  1200 	RDisplay t;
  1201 	TInt r=t.Open();
  1202 	test(r==KErrNone);
  1203 
  1204 	test.Next(_L("Test all args passed"));
  1205 	test(t.Echo(0,3,5,7,11)==3);
  1206 	test(t.Echo(1,3,5,7,11)==5);
  1207 	test(t.Echo(2,3,5,7,11)==7);
  1208 	test(t.Echo(3,3,5,7,11)==11);
  1209 	test(t.Echo(4,3,5,7,11)==26);
  1210 	test(t.Echo(5,3,5,7,11)==204);
  1211 
  1212 	test.Next(_L("Send to server"));
  1213 	r=t.Display(_L("First message"));
  1214 	test(r==KErrNone);
  1215 
  1216 	for (TInt i = 0 ; i < 4 ; ++i)
  1217 		{
  1218 		test.Start(_L("Testing passing descriptors"));
  1219 		test.Printf(_L("Descriptor passed as arg %d\n"), i);
  1220 		
  1221 		test.Next(_L("Read"));
  1222 		r=t.Read(i);
  1223 		test(r==KErrNone);
  1224 
  1225 		test.Next(_L("GetDesLength, GetDesMaxLength"));
  1226 		r=t.TestDesLength(i);
  1227 		test(r==KErrNone);
  1228 
  1229 		test.Next(_L("Write"));
  1230 		r=t.Write(i);
  1231 		test(r==KErrNone);
  1232 
  1233 		/*
  1234 		This is now explicitly not supported! 
  1235 		if (aSameProcess)
  1236 			{
  1237 			test.Next(_L("Local write"));
  1238 			r=t.LocalWrite(i);
  1239 			test(r==KErrNone);
  1240 			}
  1241 		*/
  1242 		
  1243 		test.End();
  1244 		}
  1245 
  1246 	test.Next(_L("Test RServer2::Receive to dodgy pointer"));
  1247 	BadServerTest();
  1248 
  1249 	t.Close();
  1250 
  1251 	test.End();
  1252 	}
  1253 
  1254 void RunTests()
  1255 //
  1256 // Test timers.
  1257 //
  1258     {
  1259 	test.Title();
  1260 
  1261 	// Turn off evil lazy dll unloading
  1262 	RLoader l;
  1263 	test(l.Connect()==KErrNone);
  1264 	test(l.CancelLazyDllUnload()==KErrNone);
  1265 	l.Close();
  1266 
  1267 	test.Start(_L("Running tests for server in remote process"));
  1268 
  1269 	StartServerProcess();
  1270 	RunCommonServerTests(EFalse);
  1271 	WaitServerProcessDeath();
  1272 	
  1273 	test.Next(_L("Running tests for server in same process"));
  1274 	StartServerThread();
  1275 	RunCommonServerTests(ETrue);
  1276 	WaitServerThreadDeath();
  1277 
  1278 	test.Next(_L("Running rogue thread test"));
  1279 	RogueThreadTest();
  1280 	
  1281 	test.Next(_L("Test multiple outstanding requests"));
  1282 	TestMultipleOutstandingRequests();
  1283 	
  1284 	test.Next(_L("Test sending blind async requests"));
  1285 	TestBlindMessages();	
  1286 	
  1287 #ifndef _DEBUG
  1288 	test.Next(_L("Running speed tests"));
  1289     test.Printf(_L("Server process, Test name, Time (uS)\n"));
  1290 	
  1291 	StartServerProcess();
  1292 	RunAllSpeedTests(EFalse);
  1293 	WaitServerProcessDeath();
  1294 	
  1295 	StartServerThread();
  1296 	RunAllSpeedTests(ETrue);	
  1297 	WaitServerThreadDeath();
  1298 #endif
  1299 
  1300 	test.End();
  1301     }
  1302 
  1303 
  1304 GLDEF_C TInt E32Main()
  1305 	{
  1306 	if (User::CommandLineLength() == 0)
  1307 		{
  1308 		RunTests();
  1309 		return KErrNone;
  1310 		}
  1311 	else
  1312 		return serverThreadEntryPoint(NULL);
  1313 	}