os/kernelhwsrv/kerneltest/e32test/bench/t_svr5.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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_svr5.cpp
    15 // Overview:
    16 // Test client server shareable sessions and benchmark their performance.
    17 // API information:
    18 // CSession2, CServer2, RSessionBase, RMessage2, DServer, DSession 
    19 // Details:
    20 // - Start the test server
    21 // - Open a connection with the server specifying 0 message slots should be 
    22 // available for the session and verify the server returns KErrServerBusy 
    23 // when it tries to pass a message to it.
    24 // - Open a connection using a fixed pool of messages and test that the server 
    25 // handles the messages correctly.
    26 // - Open a connection using the kernel's global pool of messages and test the 
    27 // servers handles the messages correctly.
    28 // - Open a shareable session with the server and verify that:
    29 // - all arguments are passed to the server and back correctly
    30 // - server can read and write to/from the client and return the appropriate 
    31 // errors when bad descriptors are passed in.
    32 // - another thread can share the session to send messages to the server.
    33 // - a message sent by one thread can be saved and completed later in 
    34 // response to a message sent by a different thread.
    35 // - another thread can close the session.
    36 // - a different thread can attach to a session by handle.
    37 // - Establish a global shareable session to the server and test it fails, as 
    38 // the server doesn't support global shareable sessions.
    39 // - Open an unshareable session with the server and verify that:
    40 // - all arguments are passed to the server and back correctly.
    41 // - server can reads and write to/from the client and return the 
    42 // appropriate errors when bad descriptors are passed in.
    43 // - the session handle is local (thread owned)
    44 // - Open an automatically shared session using ShareAuto and test it can be 
    45 // shared by threads in the same process.
    46 // - Send dummy messages that the server completes immediately and display how 
    47 // many are completed per second.
    48 // - Verify that stopping the server completes existing pending requests with 
    49 // KErrServerTerminated.
    50 // - Verify that the kernel does not crash by completing a message with an invalid 
    51 // handle and verify the client is panicked with EBadMessageHandle.
    52 // Platforms/Drives/Compatibility:
    53 // All.
    54 // Assumptions/Requirement/Pre-requisites:
    55 // Failures and causes:
    56 // Base Port information:
    57 // This test does not help to validate an EKA2 port.
    58 // 
    59 //
    60 
    61 #include <e32base.h>
    62 #include <e32base_private.h>
    63 #define __E32TEST_EXTENSION__
    64 #include <e32test.h>
    65 #include <e32svr.h>
    66 
    67 #include "../mmu/mmudetect.h"
    68 
    69 const TInt KHeapSize=0x2000;
    70 const TInt KMajorVersionNumber=1;
    71 const TInt KMinorVersionNumber=0;
    72 const TInt KBuildVersionNumber=1;
    73 
    74 _LIT(KServerName,"Display");
    75 
    76 TInt SessionCreateLResult=0;
    77 TInt SessionCostructCount=0;
    78 TInt SessionDestructCount=0;
    79 
    80 class CMySession : public CSession2
    81 	{
    82 public:
    83 	CMySession();
    84 	~CMySession();
    85 	void DisplayName(const RMessage2& aM);
    86 	virtual void ServiceL(const RMessage2& aMessage);
    87 	virtual void CreateL();
    88 	TInt Hold(const RMessage2& aM);
    89 	TInt Release(const RMessage2& aM);
    90 public:
    91 	RPointerArray<TInt> iAsyncMsgArray;	// 'pointers' are actually message handles
    92 	TInt iCompleteIndex;
    93 	};
    94 
    95 TInt AsyncMsgOrder(const TInt& aL, const TInt& aR)
    96 	{
    97 	TInt lh = (TInt)&aL;
    98 	TInt rh = (TInt)&aR;
    99 	RMessage2 l(*(const RMessagePtr2*)&lh);
   100 	RMessage2 r(*(const RMessagePtr2*)&rh);
   101 	return l.Int0() - r.Int0();
   102 	}
   103 
   104 TInt GetClientName(const RMessagePtr2& aM, TFullName& aN)
   105 	{
   106 	RThread t;
   107 	TInt r = aM.Client(t);
   108 	if (r==KErrNone)
   109 		{
   110 		aN = t.FullName();
   111 		t.Close();
   112 		}
   113 	return r;
   114 	}
   115 
   116 class CMyServer : public CServer2
   117 	{
   118 public:
   119 	enum {EDisplay,ERead,EWrite,ETest,EStop,EHold,ERelease,EGetCompleteIndex};
   120 public:
   121 	CMyServer(TInt aPriority);
   122 	static CMyServer* New(TInt aPriority);
   123 	virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
   124 	};
   125 
   126 class CMyActiveScheduler : public CActiveScheduler
   127 	{
   128 public:
   129 	virtual void Error(TInt anError) const;	 //Overloading pure virtual function
   130 	};
   131 
   132 class RDisplay : public RSessionBase
   133 	{
   134 public:
   135 	TInt Open();
   136 	TInt OpenNoAsync();
   137 	TInt OpenDynamic();
   138 	TInt OpenUS();
   139 	TInt OpenS();
   140 	TInt OpenGS();
   141 	TInt Display(const TDesC& aMessage);
   142 	TInt Read();
   143 	TInt Write();
   144 	TInt Stop();
   145 	TInt Test();
   146 	TInt Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3);
   147 	TVersion Version();
   148 	TInt Hold(TInt aOrder=0, TInt aArg=0);
   149 	void Hold(TRequestStatus& aStatus, TInt aOrder=0, TInt aArg=0);
   150 	TInt Release(TInt aCount=KMaxTInt);
   151 	TInt CompleteIndex();
   152 	};
   153 
   154 LOCAL_D RTest test(_L("T_SVR"));
   155 LOCAL_D RTest testSvr(_L("T_SVR Server"));
   156 LOCAL_D RTest testSpeedy(_L("T_SVR Speedy"));
   157 LOCAL_D RSemaphore client;
   158 LOCAL_D TInt speedCount;
   159 
   160 CMySession::CMySession()
   161 //
   162 // Constructor
   163 //
   164 	{
   165 	++SessionCostructCount;
   166 	}
   167 
   168 CMySession::~CMySession()
   169 	{
   170 	iAsyncMsgArray.Close();
   171 	++SessionDestructCount;
   172 	}
   173 
   174 void CMySession::CreateL()
   175 	{
   176 	User::LeaveIfError(SessionCreateLResult);
   177 	}
   178 
   179 void CMySession::DisplayName(const RMessage2& aM)
   180 //
   181 // Display the client's name.
   182 //
   183 	{
   184 
   185 	TFullName fn;
   186 	TInt r = GetClientName(aM, fn);
   187 	testSvr(r==KErrNone);
   188 	TBuf<256> text;
   189 	r=aM.Read(0,text);
   190 	testSvr(r==KErrNone);
   191 	testSvr.Printf(_L("Session %08x %S\n%S\n"), this, &fn, &text);
   192 	}
   193 
   194 CMyServer* CMyServer::New(TInt aPriority)
   195 //
   196 // Create a new CMyServer.
   197 //
   198 	{
   199 	
   200 	return new CMyServer(aPriority);
   201 	}
   202 
   203 CMyServer::CMyServer(TInt aPriority)
   204 //
   205 // Constructor.
   206 //
   207 	: CServer2(aPriority, ESharableSessions)
   208 	{}
   209 
   210 CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
   211 //
   212 // Create a new client for this server.
   213 //
   214 	{
   215 
   216 	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
   217 	if (!User::QueryVersionSupported(v,aVersion))
   218 		User::Leave(KErrNotSupported);
   219 	return new(ELeave) CMySession;
   220 	}
   221 
   222 void CMySession::ServiceL(const RMessage2& aMessage)
   223 //
   224 // Handle messages for this server.
   225 //
   226 	{
   227 
   228 	TInt f = aMessage.Function();
   229 	if (f & 0x40000000)
   230 		{
   231 		TInt what = f & 0x3fffffff;
   232 		TInt a0 = aMessage.Int0();
   233 		TInt a1 = aMessage.Int1();
   234 		TInt a2 = aMessage.Int2();
   235 		TInt a3 = aMessage.Int3();
   236 		switch (what)
   237 			{
   238 			case 0:
   239 				aMessage.Complete(a0);
   240 				return;
   241 			case 1:
   242 				aMessage.Complete(a1);
   243 				return;
   244 			case 2:
   245 				aMessage.Complete(a2);
   246 				return;
   247 			case 3:
   248 				aMessage.Complete(a3);
   249 				return;
   250 			case 4:
   251 				aMessage.Complete(a0+a1+a2+a3);
   252 				return;
   253 			case 5:
   254 				aMessage.Complete(a0*a0+a1*a1+a2*a2+a3*a3);
   255 				return;
   256 			default:
   257 				break;
   258 			}
   259 		}
   260 
   261 	TInt r=KErrNone;
   262 	TBuf<0x100> b;
   263 	switch (f)
   264 		{
   265 	case CMyServer::EDisplay:
   266 		DisplayName(aMessage);
   267 		break;
   268 	case CMyServer::ERead:
   269 		testSvr.Printf(_L("read message received\n"));
   270 		r=aMessage.Read(0,b);
   271 		if (r==KErrNone && b!=_L("Testing read"))
   272 			r=KErrGeneral;
   273 		if (r==KErrNone)
   274 			{
   275             r=aMessage.Read(0,b,-1);
   276 			if (r==KErrNone)
   277 				r=KErrGeneral;
   278 			if (r==KErrArgument)
   279 				r=KErrNone;
   280 			}
   281 		if (r==KErrNone && HaveVirtMem())
   282 			{
   283 			r=aMessage.Read(1,b);
   284 			if (r==KErrNone)
   285 				r=KErrGeneral;
   286 			if (r==KErrBadDescriptor)
   287 				r=KErrNone;
   288 			}
   289 		break;
   290 	case CMyServer::EWrite:
   291 		testSvr.Printf(_L("write message received\n"));
   292 		r=aMessage.Write(0,_L("It worked!"));
   293 		RDebug::Print(_L("Write returns %d"),r);
   294 		if (r==KErrNone)
   295 			{
   296 			r=aMessage.Write(0,b,-1);
   297 			if (r==KErrNone)
   298 				r=KErrGeneral;
   299 			if (r==KErrArgument)
   300 				r=KErrNone;
   301 			}
   302 		if (r==KErrNone)
   303 			{
   304 			r=aMessage.Write(1,b);
   305 			if (r==KErrNone)
   306 				r=KErrGeneral;
   307 			if (r==KErrBadDescriptor)
   308 				r=KErrNone;
   309 			}
   310 		if (r==KErrNone && HaveVirtMem())
   311 			{
   312 			r=aMessage.Write(2,b);
   313 			if (r==KErrNone)
   314 				r=KErrGeneral;
   315 			if (r==KErrBadDescriptor)
   316 				r=KErrNone;
   317 			}
   318 		break;
   319 	case CMyServer::ETest:
   320 		break;
   321 	case CMyServer::EStop:
   322 		testSvr.Printf(_L("stop message received\n"));
   323 		CActiveScheduler::Stop();
   324 		break;
   325 	case CMyServer::EHold:
   326 		{
   327 		r = Hold(aMessage);
   328 		if (r==KErrNone)
   329 			return;
   330 		break;
   331 		}
   332 	case CMyServer::ERelease:
   333 		{
   334 		r = Release(aMessage);
   335 		break;
   336 		}
   337 	case CMyServer::EGetCompleteIndex:
   338 		{
   339 		r = iCompleteIndex;
   340 		break;
   341 		}
   342 	default:
   343 		r=KErrNotSupported;
   344 		}
   345 	aMessage.Complete(r);
   346 	}
   347 
   348 TInt CMySession::Hold(const RMessage2& a)
   349 	{
   350 	TInt ord = a.Int0();
   351 	TInt arg = a.Int1();
   352 	TFullName fn;
   353 	TInt r = GetClientName(a, fn);
   354 	testSvr(r==KErrNone);
   355     testSvr.Printf(_L("Hold message from %S ord %08x arg %08x\n"), &fn, ord, arg);
   356 	r = iAsyncMsgArray.InsertInOrder((const TInt*)a.Handle(), &AsyncMsgOrder);
   357 	return r;
   358 	}
   359 
   360 TInt CMySession::Release(const RMessage2& a)
   361 	{
   362 	TInt req_count = a.Int0();
   363 	TInt avail = iAsyncMsgArray.Count();
   364 	TInt count = Min(req_count, avail);
   365 	TFullName fn;
   366 	TInt r = GetClientName(a, fn);
   367 	testSvr(r==KErrNone);
   368 	testSvr.Printf(_L("Release message from %S req_count=%d count=%d\n"), &fn, req_count, count);
   369 	while (count--)
   370 		{
   371 		TInt mp = (TInt)iAsyncMsgArray[0];
   372 		iAsyncMsgArray.Remove(0);
   373 		RMessage2 m(*(const RMessagePtr2*)&mp);
   374 		TInt arg = m.Int1();
   375 		TInt code = arg ? arg ^ iCompleteIndex : 0;
   376 		r = GetClientName(m, fn);
   377 		testSvr(r==KErrNone);
   378 		testSvr.Printf(_L("Releasing %S arg=%08x index=%08x code=%08x\n"), &fn, arg, iCompleteIndex, code);
   379 		++iCompleteIndex;
   380 		m.Complete(code);
   381 		}
   382 	return KErrNone;
   383 	}
   384 
   385 void CMyActiveScheduler::Error(TInt anError) const
   386 //
   387 // Called if any Run() method leaves.
   388 //
   389 	{
   390 
   391 	testSvr.Panic(anError,_L("CMyActiveScheduler::Error"));
   392 	}
   393 
   394 TInt RDisplay::Open()
   395 	{
   396 	TInt r=CreateSession(KServerName,Version(),8);	// use fixed pool of 8 slots
   397 	if (r==KErrNone)
   398 		r=ShareAuto();
   399 	return r;
   400 	}
   401 
   402 TInt RDisplay::OpenUS()
   403 	{
   404 	return CreateSession(KServerName,Version(),8,EIpcSession_Unsharable);	// use fixed pool of 8 slots
   405 	}
   406 
   407 TInt RDisplay::OpenS()
   408 	{
   409 	return CreateSession(KServerName,Version(),8,EIpcSession_Sharable);	// use fixed pool of 8 slots
   410 	}
   411 
   412 TInt RDisplay::OpenGS()
   413 	{
   414 	return CreateSession(KServerName,Version(),8,EIpcSession_GlobalSharable);	// use fixed pool of 8 slots
   415 	}
   416 
   417 TInt RDisplay::OpenNoAsync()
   418 	{
   419 
   420 	TInt r=CreateSession(KServerName,Version(),0);	// no asynchronous messages allowed
   421 	if (r==KErrNone)
   422 		r=ShareAuto();
   423 	return r;
   424 	}
   425 
   426 TInt RDisplay::OpenDynamic()
   427 	{
   428 	TInt r=CreateSession(KServerName,Version(),-1);	// use global dynamic message pool
   429 	if (r==KErrNone)
   430 		r=ShareAuto();
   431 	return r;
   432 	}
   433 
   434 TInt RDisplay::Display(const TDesC& aMessage)
   435 //
   436 // Display a message.
   437 //
   438 	{
   439 
   440 	TBuf<0x100> b(aMessage);
   441 	return SendReceive(CMyServer::EDisplay, TIpcArgs(&b));
   442 	}
   443 
   444 TInt RDisplay::Read()
   445 //
   446 // Get session to test CSession2::ReadL.
   447 //
   448 	{
   449 
   450 	TBuf<0x10> b(_L("Testing read"));
   451 	TBuf<0x10>* bad = (TBuf<0x10> *)(0x30000000);
   452 
   453 	return SendReceive(CMyServer::ERead, TIpcArgs(&b, bad));
   454 	}
   455 
   456 TInt RDisplay::Write()
   457 //
   458 // Get session to test CSession2::WriteL.
   459 //
   460 	{
   461 
   462 	TBuf<0x10> b;
   463     TBufC<0x10> c; // Bad descriptor - read only
   464 	TBuf<0x10>* bad = (TBuf<0x10> *)(0x30000000);
   465 	TInt r=SendReceive(CMyServer::EWrite, TIpcArgs(&b, &c, bad));
   466 	if (r==KErrNone && b!=_L("It worked!"))
   467 		r=KErrGeneral;
   468 	return r;
   469 	}
   470 
   471 TInt RDisplay::Test()
   472 //
   473 // Send a message and wait for completion.
   474 //
   475 	{
   476 
   477 	return SendReceive(CMyServer::ETest, TIpcArgs());
   478 	}
   479 
   480 TInt RDisplay::Stop()
   481 //
   482 // Stop the server.
   483 //
   484 	{
   485 
   486 	return SendReceive(CMyServer::EStop, TIpcArgs());
   487 	}
   488 
   489 TVersion RDisplay::Version()
   490 //
   491 // Return the current version.
   492 //
   493 	{
   494 
   495 	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
   496 	return v;
   497 	}
   498 
   499 TInt RDisplay::Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3)
   500 	{
   501 	return SendReceive(0x40000000|aWhat, TIpcArgs(a0,a1,a2,a3));
   502 	}
   503 
   504 TInt RDisplay::Hold(TInt aOrder, TInt aArg)
   505 	{
   506 
   507 	return Send(CMyServer::EHold, TIpcArgs(aOrder, aArg));
   508 	}
   509 
   510 void RDisplay::Hold(TRequestStatus& aStatus, TInt aOrder, TInt aArg)
   511 	{
   512 
   513 	SendReceive(CMyServer::EHold, TIpcArgs(aOrder, aArg), aStatus);
   514 	}
   515 
   516 TInt RDisplay::Release(TInt aCount)
   517 	{
   518 
   519 	return SendReceive(CMyServer::ERelease, TIpcArgs(aCount));
   520 	}
   521 
   522 TInt RDisplay::CompleteIndex()
   523 	{
   524 	return SendReceive(CMyServer::EGetCompleteIndex, TIpcArgs());
   525 	}
   526 
   527 TInt serverThreadEntryPoint(TAny*)
   528 //
   529 // The entry point for the producer thread.
   530 //
   531 	{
   532 
   533 	testSvr.Title();
   534 	testSvr.Start(_L("Create CActiveScheduler"));
   535 	CMyActiveScheduler* pR=new CMyActiveScheduler;
   536 	testSvr(pR!=NULL);
   537 	CActiveScheduler::Install(pR);
   538 //
   539 	testSvr.Next(_L("Create CMyServer"));
   540 	CMyServer* pS=CMyServer::New(0);
   541 	testSvr(pS!=NULL);
   542 //
   543 	testSvr.Next(_L("Start CMyServer"));
   544 	TInt r=pS->Start(KServerName);
   545 	testSvr(r==KErrNone);
   546 //
   547 	testSvr.Next(_L("Signal to client that we have started"));
   548 	client.Signal();
   549 //
   550 	testSvr.Next(_L("Start CActiveScheduler"));
   551 	CActiveScheduler::Start();
   552 //
   553 	testSvr.Next(_L("Exit server"));
   554 	delete pS;
   555 	testSvr.Close();
   556 	return(KErrNone);
   557 	}
   558 
   559 TInt speedyThreadEntryPoint(TAny* aDisplay)
   560 //
   561 // The entry point for the speed test thread.
   562 //
   563 	{
   564 
   565 	RDisplay& t=*(RDisplay*)aDisplay;
   566 	TInt r=t.Test();
   567 	testSpeedy(r==KErrNone);
   568 	speedCount=0;
   569 	client.Signal();
   570 	while ((r=t.Test())==KErrNone)
   571 		speedCount++;
   572 	testSpeedy(r==KErrServerTerminated);
   573 	return(KErrNone);
   574 	}
   575 
   576 TInt RunPanicThread(RThread& aThread)
   577 	{
   578 	TRequestStatus s;
   579 	aThread.Logon(s);
   580 	TBool jit = User::JustInTime();
   581 	User::SetJustInTime(EFalse);
   582 	aThread.Resume();
   583 	User::WaitForRequest(s);
   584 	User::SetJustInTime(jit);
   585 	return s.Int();
   586 	}
   587 
   588 TInt RogueThread1(TAny*)
   589 	{
   590 	// try to kill the kernel
   591 	RMutex mutex;
   592 	TPtrC* p=(TPtrC*)0x30000000;
   593 	mutex.CreateGlobal(*p,EOwnerProcess);	// this should panic the thread
   594 	return KErrNone;
   595 	}
   596 
   597 class RMessageT : public RMessage2
   598 	{
   599 public:
   600 	RMessageT(TLinAddr anAddr) { iFunction=0; iHandle=(TInt)anAddr; }
   601 	};
   602 
   603 TInt RogueThread2(TAny*)
   604 	{
   605 	// try to kill the kernel
   606 	RMessageT m(0x30000000);
   607 	m.Complete(KErrNone);					// this should panic the thread
   608 	return KErrNone;
   609 	}
   610 
   611 TInt RogueThread3(TAny*)
   612 	{
   613 	// try to kill the kernel
   614 	RMessageT m(0x80000000);
   615 	m.Complete(KErrNone);					// this should panic the thread
   616 	return KErrNone;
   617 	}
   618 
   619 TInt RogueThread4(TAny*)
   620 	{
   621 	// try to kill the kernel
   622 	RMessageT m(0x800fff00);				// this should be off the end of the kernel heap
   623 	m.Complete(KErrNone);					// this should panic the thread
   624 	return KErrNone;
   625 	}
   626 
   627 void DisplayThreadExitInfo(const RThread& aThread)
   628 	{
   629 	TFullName fn=aThread.FullName();
   630 	TExitType exitType=aThread.ExitType();
   631 	TInt exitReason=aThread.ExitReason();
   632 	TBuf<32> exitCat=aThread.ExitCategory();
   633 	test.Printf(_L("Thread %S exited %d,%d,%S\n"),&fn,exitType,exitReason,&exitCat);
   634 	}
   635 
   636 void RogueThreadTest()
   637 	{
   638 	RThread thread;
   639 	TInt r;
   640 	if (HaveVirtMem())
   641 		{
   642 		test.Next(_L("Rogue thread test 1"));
   643 		r=thread.Create(_L("Rogue1"),RogueThread1,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   644 		test_KErrNone(r);
   645 		RunPanicThread(thread);	// wait for rogue thread to die
   646 		DisplayThreadExitInfo(thread);
   647 		test(thread.ExitType()==EExitPanic);
   648 		test(thread.ExitReason()==ECausedException);
   649 		thread.Close();
   650 		}
   651 
   652 	test.Next(_L("Rogue thread test 2"));
   653 	r=thread.Create(_L("Rogue2"),RogueThread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   654 	test_KErrNone(r);
   655 	RunPanicThread(thread);	// wait for rogue thread to die
   656 	DisplayThreadExitInfo(thread);
   657 	test(thread.ExitType()==EExitPanic);
   658 	test(thread.ExitReason()==EBadMessageHandle);
   659 	thread.Close();
   660 
   661 	test.Next(_L("Rogue thread test 3"));
   662 	r=thread.Create(_L("Rogue3"),RogueThread3,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   663 	test_KErrNone(r);
   664 	RunPanicThread(thread);	// wait for rogue thread to die
   665 	DisplayThreadExitInfo(thread);
   666 	test(thread.ExitType()==EExitPanic);
   667 	test(thread.ExitReason()==EBadMessageHandle);
   668 	thread.Close();
   669 
   670 	test.Next(_L("Rogue thread test 4"));
   671 	r=thread.Create(_L("Rogue4"),RogueThread4,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   672 	test_KErrNone(r);
   673 	RunPanicThread(thread);	// wait for rogue thread to die
   674 	DisplayThreadExitInfo(thread);
   675 	test(thread.ExitType()==EExitPanic);
   676 	test(thread.ExitReason()==EBadMessageHandle);
   677 	thread.Close();
   678 	}
   679 
   680 TInt SecondClient(TAny* aSession)
   681 	{
   682 	RDisplay d;
   683 	d.SetHandle(TInt(aSession));
   684 	TInt r=d.Display(_L("Second client"));
   685 	if (r!=KErrNone)
   686 		return r;
   687 	r = d.Echo(0,19,31,83,487);
   688 	if (r!=19)
   689 		return -999990;
   690 	r = d.Echo(1,19,31,83,487);
   691 	if (r!=31)
   692 		return -999991;
   693 	r = d.Echo(2,19,31,83,487);
   694 	if (r!=83)
   695 		return -999992;
   696 	r = d.Echo(3,19,31,83,487);
   697 	if (r!=487)
   698 		return -999993;
   699 	r = d.Echo(4,19,31,83,487);
   700 	if (r!=620)
   701 		return -999994;
   702 	r = d.Echo(5,19,31,83,487);
   703 	if (r!=245380)
   704 		return -999995;
   705 	r=d.Read();
   706 	if (r!=KErrNone)
   707 		return r;
   708 	r=d.Write();
   709 	if (r!=KErrNone)
   710 		return r;
   711 	d.Release();
   712 	return KErrNone;
   713 	}
   714 
   715 TInt ThirdClient(TAny* aSession)
   716 	{
   717 	RDisplay d;
   718 	d.SetHandle(TInt(aSession));
   719 	TInt r=d.Display(_L("Third client"));
   720 	if (r!=KErrNone)
   721 		return r;
   722 	r=d.Hold();
   723 	if (r!=KErrNone)
   724 		return r;
   725 	r=d.Read();
   726 	if (r!=KErrNone)
   727 		return r;
   728 	r=d.Write();
   729 	if (r!=KErrNone)
   730 		return r;
   731 	return KErrNone;
   732 	}
   733 
   734 void TestSecondClient(RSessionBase& aSession)
   735 	{
   736 	RThread t;
   737 	TInt r=t.Create(_L("SecondClient"),SecondClient,0x1000,NULL,(TAny*)aSession.Handle());
   738 	test_KErrNone(r);
   739 	TRequestStatus s;
   740 	t.Logon(s);
   741 	t.Resume();
   742 	User::WaitForRequest(s);
   743 	test_KErrNone(s.Int());
   744 	t.Close();
   745 	}
   746 
   747 void TestThirdClient(RSessionBase& aSession)
   748 	{
   749 	RThread t;
   750 	TInt r=t.Create(_L("ThirdClient"),ThirdClient,0x1000,NULL,(TAny*)aSession.Handle());
   751 	test_KErrNone(r);
   752 	TRequestStatus s;
   753 	t.Logon(s);
   754 	t.Resume();
   755 	User::WaitForRequest(s);
   756 	test_KErrNone(s.Int());
   757 	t.Close();
   758 	}
   759 
   760 TInt FourthClient(TAny* aSession)
   761 	{
   762 	RDisplay d;
   763 	d.SetHandle(TInt(aSession));
   764 	TInt r=d.Display(_L("Fourth client"));
   765 	if (r!=KErrNone)
   766 		return r;
   767 	d.Close();
   768 	return KErrNone;
   769 	}
   770 
   771 void TestSessionClose()
   772 	{
   773 	RDisplay d;
   774 	TInt r=d.Open();
   775 	test_KErrNone(r);
   776 	TRequestStatus msgStat;
   777 	d.Hold(msgStat);
   778 	test(msgStat==KRequestPending);
   779 	RThread t;
   780 	r=t.Create(_L("FourthClient"),FourthClient,0x1000,NULL,(TAny*)d.Handle());
   781 	test_KErrNone(r);
   782 	TRequestStatus s;
   783 	t.Logon(s);
   784 	t.Resume();
   785 	User::WaitForRequest(s);
   786 	test_KErrNone(s.Int());
   787 	t.Close();
   788 	User::After(1000000);
   789 	test(msgStat==KRequestPending);
   790 	}
   791 
   792 TInt FifthClient(TAny* aDisplay)
   793 	{
   794 	RDisplay& d=*(RDisplay*)aDisplay;
   795 	TInt r=d.Open();
   796 	if (r!=KErrNone)
   797 		return r;
   798 	r=d.Display(_L("Fifth client"));
   799 	if (r!=KErrNone)
   800 		return r;
   801 	return KErrNone;
   802 	}
   803 
   804 void TestZeroShares()
   805 	{
   806 	RDisplay d;
   807 	d.SetHandle(0);
   808 	RThread t;
   809 	TInt r=t.Create(_L("FifthClient"),FifthClient,0x1000,NULL,&d);
   810 	test_KErrNone(r);
   811 	TRequestStatus s;
   812 	t.Logon(s);
   813 	t.Resume();
   814 	User::WaitForRequest(s);
   815 	test_KErrNone(s.Int());
   816 	test(d.Handle()!=0);
   817 	t.Close();
   818 	r=d.Display(_L("Access after last share closed"));
   819 	test_KErrNone(r);
   820 	d.Close();
   821 	}
   822 
   823 TInt AttachClient1(TAny* aSession)
   824 	{
   825 	RDisplay d;
   826 	d.SetHandle(TInt(aSession));
   827 	__KHEAP_MARK;
   828 	TInt r=d.Display(_L("Attach client 1"));
   829 	__KHEAP_MARKEND;	// shouldn't need to allocate memory
   830 	return r;
   831 	}
   832 
   833 TInt AttachClient2(TAny* aSession)
   834 	{
   835 	RDisplay d;
   836 	d.SetHandle(TInt(aSession));
   837 	TInt r=d.Display(_L("Attach client 2"));
   838 	if (r!=KErrNone)
   839 		return r;
   840 	__KHEAP_MARK;
   841 	r=d.Display(_L("Attach client 2"));
   842 	__KHEAP_MARKEND;	// check no memory was allocated by message send
   843 	return r;
   844 	}
   845 
   846 void TestAttach(RSessionBase& aSession)
   847 	{
   848 	test.Next(_L("Test Attach"));
   849 	RThread t;
   850 	TInt r=t.Create(_L("AttachClient1"),AttachClient1,0x1000,NULL,(TAny*)aSession.Handle());
   851 	test_KErrNone(r);
   852 	r=RunPanicThread(t);	// wait for thread to die
   853 	test_KErrNone(r);
   854 	test(t.ExitType()==EExitKill);
   855 	test_KErrNone(t.ExitReason());
   856 	t.Close();
   857 
   858 	r=t.Create(_L("AttachClient2"),AttachClient2,0x1000,NULL,(TAny*)aSession.Handle());
   859 	test_KErrNone(r);
   860 	TRequestStatus s;
   861 	t.Logon(s);
   862 	t.Resume();
   863 	User::WaitForRequest(s);
   864 	test_KErrNone(s.Int());
   865 	test(t.ExitType()==EExitKill);
   866 	test_KErrNone(t.ExitReason());
   867 	t.Close();
   868 	}
   869 
   870 TInt SixthClient(TAny* aDisplay)
   871 	{
   872 	RDisplay& d=*(RDisplay*)aDisplay;
   873 	TInt r=d.Display(_L("Sixth client"));
   874 	if (r!=KErrNone)
   875 		return r;
   876 	TRequestStatus s;
   877 	User::WaitForRequest(s);
   878 	return KErrNone;
   879 	}
   880 
   881 TInt SeventhClient(TAny* aDisplay)
   882 	{
   883 	RDisplay& d=*(RDisplay*)aDisplay;
   884 	TInt r=d.Display(_L("Seventh client"));
   885 	if (r!=KErrNone)
   886 		return r;
   887 	TRequestStatus s;
   888 	User::WaitForRequest(s);
   889 	return KErrNone;
   890 	}
   891 
   892 TInt EighthClient(TAny* aDisplay)
   893 	{
   894 	RDisplay& d=*(RDisplay*)aDisplay;
   895 	TInt r=d.Display(_L("Eighth client"));
   896 	if (r!=KErrNone)
   897 		return r;
   898 	TRequestStatus s;
   899 	User::WaitForRequest(s);
   900 	return KErrNone;
   901 	}
   902 
   903 TInt NinthClient(TAny* aDisplay)
   904 	{
   905 	RDisplay& d=*(RDisplay*)aDisplay;
   906 	TInt r=d.Display(_L("Ninth client"));
   907 	if (r!=KErrNone)
   908 		return r;
   909 	TRequestStatus s;
   910 	User::WaitForRequest(s);
   911 	return KErrNone;
   912 	}
   913 
   914 void TestAsync(RDisplay& aD)
   915 	{
   916 	TInt ci = aD.CompleteIndex();
   917 	TRequestStatus s[128];
   918 	TInt i;
   919 	TInt r;
   920 	for (i=0; i<128; ++i)
   921 		{
   922 		TInt ord = i ^ 0x55;
   923 		TInt arg = i + 1;
   924 		aD.Hold(s[i], ord, arg);
   925 		if (s[i]==KErrServerBusy)
   926 			{
   927 			User::WaitForRequest(s[i]);
   928 			break;
   929 			}
   930 		test(s[i]==KRequestPending);
   931 		}
   932 	r = aD.Release();
   933 	test_KErrNone(r);
   934 	TInt j;
   935 	for (j=0; j<128; ++j)
   936 		{
   937 		if ( (j^0x55) >= i )
   938 			continue;
   939 		TInt code = s[j^0x55].Int();
   940 		TInt expected = ci ^ ((j^0x55)+1);
   941 		if (code != expected)
   942 			{
   943 			test.Printf(_L("j=%02x i=%02x expected=%08x got=%08x\n"),j,j^0x55,expected,code);
   944 			test(0);
   945 			}
   946 		User::WaitForRequest(s[j^0x55]);
   947 		++ci;
   948 		}
   949 	}
   950 
   951 void TestSession(RDisplay& aSess)
   952 	{
   953 //
   954 	TInt r;
   955 	test.Next(_L("Test all args passed"));
   956 	test(aSess.Echo(0,3,5,7,11)==3);
   957 	test(aSess.Echo(1,3,5,7,11)==5);
   958 	test(aSess.Echo(2,3,5,7,11)==7);
   959 	test(aSess.Echo(3,3,5,7,11)==11);
   960 	test(aSess.Echo(4,3,5,7,11)==26);
   961 	test(aSess.Echo(5,3,5,7,11)==204);
   962 //
   963 	test.Next(_L("Send to server"));
   964 	r=aSess.Display(_L("First message"));
   965 	test_KErrNone(r);
   966 //
   967 	test.Next(_L("Read"));
   968 	r=aSess.Read();
   969 	test_KErrNone(r);
   970 //
   971 	test.Next(_L("Write"));
   972 	r=aSess.Write();
   973 	test_KErrNone(r);
   974 //
   975 	TestThirdClient(aSess);
   976 	User::After(1000000);
   977 	TestSecondClient(aSess);
   978 	User::After(1000000);
   979 	TestSessionClose();
   980 	User::After(1000000);
   981 	TestZeroShares();
   982 	User::After(1000000);
   983 	TestAttach(aSess);
   984 	User::After(1000000);
   985 	}
   986 
   987 void TestUnsharableSession(RDisplay& aSess)
   988 	{
   989 //
   990 	TInt r;
   991 	test.Next(_L("Test all args passed"));
   992 	test(aSess.Echo(0,3,5,7,11)==3);
   993 	test(aSess.Echo(1,3,5,7,11)==5);
   994 	test(aSess.Echo(2,3,5,7,11)==7);
   995 	test(aSess.Echo(3,3,5,7,11)==11);
   996 	test(aSess.Echo(4,3,5,7,11)==26);
   997 	test(aSess.Echo(5,3,5,7,11)==204);
   998 //
   999 	test.Next(_L("Send to server"));
  1000 	r=aSess.Display(_L("First message"));
  1001 	test_KErrNone(r);
  1002 //
  1003 	test.Next(_L("Read"));
  1004 	r=aSess.Read();
  1005 	test_KErrNone(r);
  1006 //
  1007 	test.Next(_L("Write"));
  1008 	r=aSess.Write();
  1009 	test_KErrNone(r);
  1010 //
  1011 	TInt h = aSess.Handle();
  1012 	test.Printf(_L("HANDLE %08x\n"), h);
  1013 	test((h & KHandleFlagLocal)!=0);
  1014 	}
  1015 
  1016 void TestSessionCreateLLeaving()
  1017 	{
  1018 	SessionCreateLResult=KErrGeneral;
  1019 
  1020 	TInt c=SessionCostructCount;
  1021 	TInt d=SessionDestructCount;
  1022 
  1023 	RDisplay t;
  1024 	TInt r = t.Open();
  1025 	test(r==SessionCreateLResult);
  1026 
  1027 	test(SessionCostructCount==c+1);
  1028 	test(SessionDestructCount==d+1);
  1029 
  1030 	SessionCreateLResult=KErrNone;
  1031 	}
  1032 
  1033 GLDEF_C TInt E32Main()
  1034 //
  1035 // Test timers.
  1036 //
  1037     {
  1038 
  1039 	test.Title();
  1040 	test.Start(_L("Creating client semaphore"));
  1041 	TInt r=client.CreateLocal(0);
  1042 	test_KErrNone(r);
  1043 //
  1044 	test.Next(_L("Creating server thread"));
  1045 	RThread server;
  1046 	r=server.Create(_L("Server"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
  1047 	test_KErrNone(r);
  1048 	server.SetPriority(EPriorityMore);
  1049 //
  1050 	test.Next(_L("Resume server thread"));
  1051 	server.Resume();
  1052 	test(ETrue);
  1053 //
  1054 	test.Next(_L("Wait for server to start"));
  1055 	client.Wait();
  1056 //
  1057 	test.Next(_L("Connect to server"));
  1058 	RDisplay t;
  1059 	r = t.OpenNoAsync();
  1060 	test_KErrNone(r);
  1061 	test.Next(_L("Send to server"));
  1062 	r=t.Display(_L("AsyncMsg"));
  1063 	test_KErrNone(r);
  1064 	TRequestStatus s0;
  1065 	t.Hold(s0);
  1066 	test(s0==KErrServerBusy);
  1067 	t.Close();
  1068 //
  1069 	test.Next(_L("Test Session::CreateL leaving"));
  1070 	TestSessionCreateLLeaving();
  1071 //
  1072 	test.Next(_L("Async fixed pool"));
  1073 	r = t.Open();
  1074 	test_KErrNone(r);
  1075 	TestAsync(t);
  1076 	TestAsync(t);
  1077 	t.Close();
  1078 	test.Next(_L("Async global pool"));
  1079 	r = t.OpenDynamic();
  1080 	test_KErrNone(r);
  1081 	TestAsync(t);
  1082 	TestAsync(t);
  1083 	t.Close();
  1084 //
  1085 	r=t.Open();
  1086 	test_KErrNone(r);
  1087 //
  1088 	TestSession(t);
  1089 //
  1090 	RDisplay tt;
  1091 	r = tt.OpenS();
  1092 	test.Printf(_L("OpenS -> %d\n"),r);
  1093 	test_KErrNone(r);
  1094 	TestSession(tt);
  1095 	tt.Close();
  1096 //
  1097 	r = tt.OpenGS();
  1098 	test.Printf(_L("OpenGS -> %d\n"),r);
  1099 	test(r==KErrPermissionDenied);
  1100 	tt.Close();
  1101 //
  1102 	r = tt.OpenUS();
  1103 	test.Printf(_L("OpenUS -> %d\n"),r);
  1104 	test_KErrNone(r);
  1105 	TestUnsharableSession(tt);
  1106 	tt.Close();
  1107 //
  1108 	test.Next(_L("Starting speedy client"));
  1109 	RThread speedy;
  1110 	TRequestStatus speedyStat;
  1111 	r=speedy.Create(_L("Speedy"),speedyThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,&t);
  1112 	test_KErrNone(r);
  1113 	speedy.Logon(speedyStat);
  1114 	RThread t1;
  1115 	RThread t2;
  1116 	RThread t3;
  1117 	RThread t4;
  1118 	TRequestStatus s1;
  1119 	TRequestStatus s2;
  1120 	TRequestStatus s3;
  1121 	TRequestStatus s4;
  1122 	r=t1.Create(_L("SixthClient"),SixthClient,0x1000,NULL,&t);
  1123 	test_KErrNone(r);
  1124 	t1.Logon(s1);
  1125 	r=t2.Create(_L("SeventhClient"),SeventhClient,0x1000,NULL,&t);
  1126 	test_KErrNone(r);
  1127 	t2.Logon(s2);
  1128 	r=t3.Create(_L("EighthClient"),EighthClient,0x1000,NULL,&t);
  1129 	test_KErrNone(r);
  1130 	t3.Logon(s3);
  1131 	r=t4.Create(_L("NinthClient"),NinthClient,0x1000,NULL,&t);
  1132 	test_KErrNone(r);
  1133 	t4.Logon(s4);
  1134 	t1.Resume();
  1135 	t2.Resume();
  1136 	t3.Resume();
  1137 	t4.Resume();
  1138 	User::After(1000000);
  1139 //
  1140 	test.Next(_L("Wait for speedy to start"));
  1141     speedy.SetPriority(EPriorityNormal);
  1142 	RThread().SetPriority(EPriorityMuchMore);
  1143 	speedy.Resume();
  1144 	client.Wait();
  1145 //
  1146 	test.Printf(_L("Starting speed test...\n"));
  1147     User::After(300000);
  1148     TInt b=speedCount;
  1149     User::After(3000000);
  1150     TInt n=speedCount;
  1151     test.Printf(_L("Count = %d in 1 second\n"),(n-b)/3);
  1152 //
  1153 	test.Next(_L("Stop server"));
  1154 	r=t.Stop();
  1155 	test_KErrNone(r);
  1156 	User::After(0); // Allow the speed client to die
  1157 //
  1158 	test.Next(_L("Close extra threads"));
  1159 	t1.Kill(0);
  1160 	User::WaitForRequest(s1);
  1161 	test(t1.ExitType()==EExitKill && s1==KErrNone);
  1162 	t2.Kill(0);
  1163 	User::WaitForRequest(s2);
  1164 	test(t2.ExitType()==EExitKill && s2==KErrNone);
  1165 	t3.Kill(0);
  1166 	User::WaitForRequest(s3);
  1167 	test(t3.ExitType()==EExitKill && s3==KErrNone);
  1168 	t4.Kill(0);
  1169 	User::WaitForRequest(s4);
  1170 	test(t4.ExitType()==EExitKill && s4==KErrNone);
  1171 	User::WaitForRequest(speedyStat);
  1172 	test(speedy.ExitType()==EExitKill && speedyStat==KErrNone);
  1173 //
  1174 	test.Next(_L("Close all"));
  1175 	t1.Close();
  1176 	t2.Close();
  1177 	t3.Close();
  1178 	t4.Close();
  1179 	speedy.Close();
  1180 	server.Close();
  1181 	client.Close();
  1182 //
  1183 	test.Next(_L("Close connection"));
  1184 	t.Close();
  1185 //
  1186 	RogueThreadTest();
  1187 //
  1188 	test.End();
  1189 	return(0);
  1190     }
  1191