kerneltest/e32test/bench/t_svr.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}