kerneltest/e32test/bench/t_svr5.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_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