1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/bench/t_svr5.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1191 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\bench\t_svr5.cpp
1.18 +// Overview:
1.19 +// Test client server shareable sessions and benchmark their performance.
1.20 +// API information:
1.21 +// CSession2, CServer2, RSessionBase, RMessage2, DServer, DSession
1.22 +// Details:
1.23 +// - Start the test server
1.24 +// - Open a connection with the server specifying 0 message slots should be
1.25 +// available for the session and verify the server returns KErrServerBusy
1.26 +// when it tries to pass a message to it.
1.27 +// - Open a connection using a fixed pool of messages and test that the server
1.28 +// handles the messages correctly.
1.29 +// - Open a connection using the kernel's global pool of messages and test the
1.30 +// servers handles the messages correctly.
1.31 +// - Open a shareable session with the server and verify that:
1.32 +// - all arguments are passed to the server and back correctly
1.33 +// - server can read and write to/from the client and return the appropriate
1.34 +// errors when bad descriptors are passed in.
1.35 +// - another thread can share the session to send messages to the server.
1.36 +// - a message sent by one thread can be saved and completed later in
1.37 +// response to a message sent by a different thread.
1.38 +// - another thread can close the session.
1.39 +// - a different thread can attach to a session by handle.
1.40 +// - Establish a global shareable session to the server and test it fails, as
1.41 +// the server doesn't support global shareable sessions.
1.42 +// - Open an unshareable session with the server and verify that:
1.43 +// - all arguments are passed to the server and back correctly.
1.44 +// - server can reads and write to/from the client and return the
1.45 +// appropriate errors when bad descriptors are passed in.
1.46 +// - the session handle is local (thread owned)
1.47 +// - Open an automatically shared session using ShareAuto and test it can be
1.48 +// shared by threads in the same process.
1.49 +// - Send dummy messages that the server completes immediately and display how
1.50 +// many are completed per second.
1.51 +// - Verify that stopping the server completes existing pending requests with
1.52 +// KErrServerTerminated.
1.53 +// - Verify that the kernel does not crash by completing a message with an invalid
1.54 +// handle and verify the client is panicked with EBadMessageHandle.
1.55 +// Platforms/Drives/Compatibility:
1.56 +// All.
1.57 +// Assumptions/Requirement/Pre-requisites:
1.58 +// Failures and causes:
1.59 +// Base Port information:
1.60 +// This test does not help to validate an EKA2 port.
1.61 +//
1.62 +//
1.63 +
1.64 +#include <e32base.h>
1.65 +#include <e32base_private.h>
1.66 +#define __E32TEST_EXTENSION__
1.67 +#include <e32test.h>
1.68 +#include <e32svr.h>
1.69 +
1.70 +#include "../mmu/mmudetect.h"
1.71 +
1.72 +const TInt KHeapSize=0x2000;
1.73 +const TInt KMajorVersionNumber=1;
1.74 +const TInt KMinorVersionNumber=0;
1.75 +const TInt KBuildVersionNumber=1;
1.76 +
1.77 +_LIT(KServerName,"Display");
1.78 +
1.79 +TInt SessionCreateLResult=0;
1.80 +TInt SessionCostructCount=0;
1.81 +TInt SessionDestructCount=0;
1.82 +
1.83 +class CMySession : public CSession2
1.84 + {
1.85 +public:
1.86 + CMySession();
1.87 + ~CMySession();
1.88 + void DisplayName(const RMessage2& aM);
1.89 + virtual void ServiceL(const RMessage2& aMessage);
1.90 + virtual void CreateL();
1.91 + TInt Hold(const RMessage2& aM);
1.92 + TInt Release(const RMessage2& aM);
1.93 +public:
1.94 + RPointerArray<TInt> iAsyncMsgArray; // 'pointers' are actually message handles
1.95 + TInt iCompleteIndex;
1.96 + };
1.97 +
1.98 +TInt AsyncMsgOrder(const TInt& aL, const TInt& aR)
1.99 + {
1.100 + TInt lh = (TInt)&aL;
1.101 + TInt rh = (TInt)&aR;
1.102 + RMessage2 l(*(const RMessagePtr2*)&lh);
1.103 + RMessage2 r(*(const RMessagePtr2*)&rh);
1.104 + return l.Int0() - r.Int0();
1.105 + }
1.106 +
1.107 +TInt GetClientName(const RMessagePtr2& aM, TFullName& aN)
1.108 + {
1.109 + RThread t;
1.110 + TInt r = aM.Client(t);
1.111 + if (r==KErrNone)
1.112 + {
1.113 + aN = t.FullName();
1.114 + t.Close();
1.115 + }
1.116 + return r;
1.117 + }
1.118 +
1.119 +class CMyServer : public CServer2
1.120 + {
1.121 +public:
1.122 + enum {EDisplay,ERead,EWrite,ETest,EStop,EHold,ERelease,EGetCompleteIndex};
1.123 +public:
1.124 + CMyServer(TInt aPriority);
1.125 + static CMyServer* New(TInt aPriority);
1.126 + virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
1.127 + };
1.128 +
1.129 +class CMyActiveScheduler : public CActiveScheduler
1.130 + {
1.131 +public:
1.132 + virtual void Error(TInt anError) const; //Overloading pure virtual function
1.133 + };
1.134 +
1.135 +class RDisplay : public RSessionBase
1.136 + {
1.137 +public:
1.138 + TInt Open();
1.139 + TInt OpenNoAsync();
1.140 + TInt OpenDynamic();
1.141 + TInt OpenUS();
1.142 + TInt OpenS();
1.143 + TInt OpenGS();
1.144 + TInt Display(const TDesC& aMessage);
1.145 + TInt Read();
1.146 + TInt Write();
1.147 + TInt Stop();
1.148 + TInt Test();
1.149 + TInt Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3);
1.150 + TVersion Version();
1.151 + TInt Hold(TInt aOrder=0, TInt aArg=0);
1.152 + void Hold(TRequestStatus& aStatus, TInt aOrder=0, TInt aArg=0);
1.153 + TInt Release(TInt aCount=KMaxTInt);
1.154 + TInt CompleteIndex();
1.155 + };
1.156 +
1.157 +LOCAL_D RTest test(_L("T_SVR"));
1.158 +LOCAL_D RTest testSvr(_L("T_SVR Server"));
1.159 +LOCAL_D RTest testSpeedy(_L("T_SVR Speedy"));
1.160 +LOCAL_D RSemaphore client;
1.161 +LOCAL_D TInt speedCount;
1.162 +
1.163 +CMySession::CMySession()
1.164 +//
1.165 +// Constructor
1.166 +//
1.167 + {
1.168 + ++SessionCostructCount;
1.169 + }
1.170 +
1.171 +CMySession::~CMySession()
1.172 + {
1.173 + iAsyncMsgArray.Close();
1.174 + ++SessionDestructCount;
1.175 + }
1.176 +
1.177 +void CMySession::CreateL()
1.178 + {
1.179 + User::LeaveIfError(SessionCreateLResult);
1.180 + }
1.181 +
1.182 +void CMySession::DisplayName(const RMessage2& aM)
1.183 +//
1.184 +// Display the client's name.
1.185 +//
1.186 + {
1.187 +
1.188 + TFullName fn;
1.189 + TInt r = GetClientName(aM, fn);
1.190 + testSvr(r==KErrNone);
1.191 + TBuf<256> text;
1.192 + r=aM.Read(0,text);
1.193 + testSvr(r==KErrNone);
1.194 + testSvr.Printf(_L("Session %08x %S\n%S\n"), this, &fn, &text);
1.195 + }
1.196 +
1.197 +CMyServer* CMyServer::New(TInt aPriority)
1.198 +//
1.199 +// Create a new CMyServer.
1.200 +//
1.201 + {
1.202 +
1.203 + return new CMyServer(aPriority);
1.204 + }
1.205 +
1.206 +CMyServer::CMyServer(TInt aPriority)
1.207 +//
1.208 +// Constructor.
1.209 +//
1.210 + : CServer2(aPriority, ESharableSessions)
1.211 + {}
1.212 +
1.213 +CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
1.214 +//
1.215 +// Create a new client for this server.
1.216 +//
1.217 + {
1.218 +
1.219 + TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.220 + if (!User::QueryVersionSupported(v,aVersion))
1.221 + User::Leave(KErrNotSupported);
1.222 + return new(ELeave) CMySession;
1.223 + }
1.224 +
1.225 +void CMySession::ServiceL(const RMessage2& aMessage)
1.226 +//
1.227 +// Handle messages for this server.
1.228 +//
1.229 + {
1.230 +
1.231 + TInt f = aMessage.Function();
1.232 + if (f & 0x40000000)
1.233 + {
1.234 + TInt what = f & 0x3fffffff;
1.235 + TInt a0 = aMessage.Int0();
1.236 + TInt a1 = aMessage.Int1();
1.237 + TInt a2 = aMessage.Int2();
1.238 + TInt a3 = aMessage.Int3();
1.239 + switch (what)
1.240 + {
1.241 + case 0:
1.242 + aMessage.Complete(a0);
1.243 + return;
1.244 + case 1:
1.245 + aMessage.Complete(a1);
1.246 + return;
1.247 + case 2:
1.248 + aMessage.Complete(a2);
1.249 + return;
1.250 + case 3:
1.251 + aMessage.Complete(a3);
1.252 + return;
1.253 + case 4:
1.254 + aMessage.Complete(a0+a1+a2+a3);
1.255 + return;
1.256 + case 5:
1.257 + aMessage.Complete(a0*a0+a1*a1+a2*a2+a3*a3);
1.258 + return;
1.259 + default:
1.260 + break;
1.261 + }
1.262 + }
1.263 +
1.264 + TInt r=KErrNone;
1.265 + TBuf<0x100> b;
1.266 + switch (f)
1.267 + {
1.268 + case CMyServer::EDisplay:
1.269 + DisplayName(aMessage);
1.270 + break;
1.271 + case CMyServer::ERead:
1.272 + testSvr.Printf(_L("read message received\n"));
1.273 + r=aMessage.Read(0,b);
1.274 + if (r==KErrNone && b!=_L("Testing read"))
1.275 + r=KErrGeneral;
1.276 + if (r==KErrNone)
1.277 + {
1.278 + r=aMessage.Read(0,b,-1);
1.279 + if (r==KErrNone)
1.280 + r=KErrGeneral;
1.281 + if (r==KErrArgument)
1.282 + r=KErrNone;
1.283 + }
1.284 + if (r==KErrNone && HaveVirtMem())
1.285 + {
1.286 + r=aMessage.Read(1,b);
1.287 + if (r==KErrNone)
1.288 + r=KErrGeneral;
1.289 + if (r==KErrBadDescriptor)
1.290 + r=KErrNone;
1.291 + }
1.292 + break;
1.293 + case CMyServer::EWrite:
1.294 + testSvr.Printf(_L("write message received\n"));
1.295 + r=aMessage.Write(0,_L("It worked!"));
1.296 + RDebug::Print(_L("Write returns %d"),r);
1.297 + if (r==KErrNone)
1.298 + {
1.299 + r=aMessage.Write(0,b,-1);
1.300 + if (r==KErrNone)
1.301 + r=KErrGeneral;
1.302 + if (r==KErrArgument)
1.303 + r=KErrNone;
1.304 + }
1.305 + if (r==KErrNone)
1.306 + {
1.307 + r=aMessage.Write(1,b);
1.308 + if (r==KErrNone)
1.309 + r=KErrGeneral;
1.310 + if (r==KErrBadDescriptor)
1.311 + r=KErrNone;
1.312 + }
1.313 + if (r==KErrNone && HaveVirtMem())
1.314 + {
1.315 + r=aMessage.Write(2,b);
1.316 + if (r==KErrNone)
1.317 + r=KErrGeneral;
1.318 + if (r==KErrBadDescriptor)
1.319 + r=KErrNone;
1.320 + }
1.321 + break;
1.322 + case CMyServer::ETest:
1.323 + break;
1.324 + case CMyServer::EStop:
1.325 + testSvr.Printf(_L("stop message received\n"));
1.326 + CActiveScheduler::Stop();
1.327 + break;
1.328 + case CMyServer::EHold:
1.329 + {
1.330 + r = Hold(aMessage);
1.331 + if (r==KErrNone)
1.332 + return;
1.333 + break;
1.334 + }
1.335 + case CMyServer::ERelease:
1.336 + {
1.337 + r = Release(aMessage);
1.338 + break;
1.339 + }
1.340 + case CMyServer::EGetCompleteIndex:
1.341 + {
1.342 + r = iCompleteIndex;
1.343 + break;
1.344 + }
1.345 + default:
1.346 + r=KErrNotSupported;
1.347 + }
1.348 + aMessage.Complete(r);
1.349 + }
1.350 +
1.351 +TInt CMySession::Hold(const RMessage2& a)
1.352 + {
1.353 + TInt ord = a.Int0();
1.354 + TInt arg = a.Int1();
1.355 + TFullName fn;
1.356 + TInt r = GetClientName(a, fn);
1.357 + testSvr(r==KErrNone);
1.358 + testSvr.Printf(_L("Hold message from %S ord %08x arg %08x\n"), &fn, ord, arg);
1.359 + r = iAsyncMsgArray.InsertInOrder((const TInt*)a.Handle(), &AsyncMsgOrder);
1.360 + return r;
1.361 + }
1.362 +
1.363 +TInt CMySession::Release(const RMessage2& a)
1.364 + {
1.365 + TInt req_count = a.Int0();
1.366 + TInt avail = iAsyncMsgArray.Count();
1.367 + TInt count = Min(req_count, avail);
1.368 + TFullName fn;
1.369 + TInt r = GetClientName(a, fn);
1.370 + testSvr(r==KErrNone);
1.371 + testSvr.Printf(_L("Release message from %S req_count=%d count=%d\n"), &fn, req_count, count);
1.372 + while (count--)
1.373 + {
1.374 + TInt mp = (TInt)iAsyncMsgArray[0];
1.375 + iAsyncMsgArray.Remove(0);
1.376 + RMessage2 m(*(const RMessagePtr2*)&mp);
1.377 + TInt arg = m.Int1();
1.378 + TInt code = arg ? arg ^ iCompleteIndex : 0;
1.379 + r = GetClientName(m, fn);
1.380 + testSvr(r==KErrNone);
1.381 + testSvr.Printf(_L("Releasing %S arg=%08x index=%08x code=%08x\n"), &fn, arg, iCompleteIndex, code);
1.382 + ++iCompleteIndex;
1.383 + m.Complete(code);
1.384 + }
1.385 + return KErrNone;
1.386 + }
1.387 +
1.388 +void CMyActiveScheduler::Error(TInt anError) const
1.389 +//
1.390 +// Called if any Run() method leaves.
1.391 +//
1.392 + {
1.393 +
1.394 + testSvr.Panic(anError,_L("CMyActiveScheduler::Error"));
1.395 + }
1.396 +
1.397 +TInt RDisplay::Open()
1.398 + {
1.399 + TInt r=CreateSession(KServerName,Version(),8); // use fixed pool of 8 slots
1.400 + if (r==KErrNone)
1.401 + r=ShareAuto();
1.402 + return r;
1.403 + }
1.404 +
1.405 +TInt RDisplay::OpenUS()
1.406 + {
1.407 + return CreateSession(KServerName,Version(),8,EIpcSession_Unsharable); // use fixed pool of 8 slots
1.408 + }
1.409 +
1.410 +TInt RDisplay::OpenS()
1.411 + {
1.412 + return CreateSession(KServerName,Version(),8,EIpcSession_Sharable); // use fixed pool of 8 slots
1.413 + }
1.414 +
1.415 +TInt RDisplay::OpenGS()
1.416 + {
1.417 + return CreateSession(KServerName,Version(),8,EIpcSession_GlobalSharable); // use fixed pool of 8 slots
1.418 + }
1.419 +
1.420 +TInt RDisplay::OpenNoAsync()
1.421 + {
1.422 +
1.423 + TInt r=CreateSession(KServerName,Version(),0); // no asynchronous messages allowed
1.424 + if (r==KErrNone)
1.425 + r=ShareAuto();
1.426 + return r;
1.427 + }
1.428 +
1.429 +TInt RDisplay::OpenDynamic()
1.430 + {
1.431 + TInt r=CreateSession(KServerName,Version(),-1); // use global dynamic message pool
1.432 + if (r==KErrNone)
1.433 + r=ShareAuto();
1.434 + return r;
1.435 + }
1.436 +
1.437 +TInt RDisplay::Display(const TDesC& aMessage)
1.438 +//
1.439 +// Display a message.
1.440 +//
1.441 + {
1.442 +
1.443 + TBuf<0x100> b(aMessage);
1.444 + return SendReceive(CMyServer::EDisplay, TIpcArgs(&b));
1.445 + }
1.446 +
1.447 +TInt RDisplay::Read()
1.448 +//
1.449 +// Get session to test CSession2::ReadL.
1.450 +//
1.451 + {
1.452 +
1.453 + TBuf<0x10> b(_L("Testing read"));
1.454 + TBuf<0x10>* bad = (TBuf<0x10> *)(0x30000000);
1.455 +
1.456 + return SendReceive(CMyServer::ERead, TIpcArgs(&b, bad));
1.457 + }
1.458 +
1.459 +TInt RDisplay::Write()
1.460 +//
1.461 +// Get session to test CSession2::WriteL.
1.462 +//
1.463 + {
1.464 +
1.465 + TBuf<0x10> b;
1.466 + TBufC<0x10> c; // Bad descriptor - read only
1.467 + TBuf<0x10>* bad = (TBuf<0x10> *)(0x30000000);
1.468 + TInt r=SendReceive(CMyServer::EWrite, TIpcArgs(&b, &c, bad));
1.469 + if (r==KErrNone && b!=_L("It worked!"))
1.470 + r=KErrGeneral;
1.471 + return r;
1.472 + }
1.473 +
1.474 +TInt RDisplay::Test()
1.475 +//
1.476 +// Send a message and wait for completion.
1.477 +//
1.478 + {
1.479 +
1.480 + return SendReceive(CMyServer::ETest, TIpcArgs());
1.481 + }
1.482 +
1.483 +TInt RDisplay::Stop()
1.484 +//
1.485 +// Stop the server.
1.486 +//
1.487 + {
1.488 +
1.489 + return SendReceive(CMyServer::EStop, TIpcArgs());
1.490 + }
1.491 +
1.492 +TVersion RDisplay::Version()
1.493 +//
1.494 +// Return the current version.
1.495 +//
1.496 + {
1.497 +
1.498 + TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.499 + return v;
1.500 + }
1.501 +
1.502 +TInt RDisplay::Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3)
1.503 + {
1.504 + return SendReceive(0x40000000|aWhat, TIpcArgs(a0,a1,a2,a3));
1.505 + }
1.506 +
1.507 +TInt RDisplay::Hold(TInt aOrder, TInt aArg)
1.508 + {
1.509 +
1.510 + return Send(CMyServer::EHold, TIpcArgs(aOrder, aArg));
1.511 + }
1.512 +
1.513 +void RDisplay::Hold(TRequestStatus& aStatus, TInt aOrder, TInt aArg)
1.514 + {
1.515 +
1.516 + SendReceive(CMyServer::EHold, TIpcArgs(aOrder, aArg), aStatus);
1.517 + }
1.518 +
1.519 +TInt RDisplay::Release(TInt aCount)
1.520 + {
1.521 +
1.522 + return SendReceive(CMyServer::ERelease, TIpcArgs(aCount));
1.523 + }
1.524 +
1.525 +TInt RDisplay::CompleteIndex()
1.526 + {
1.527 + return SendReceive(CMyServer::EGetCompleteIndex, TIpcArgs());
1.528 + }
1.529 +
1.530 +TInt serverThreadEntryPoint(TAny*)
1.531 +//
1.532 +// The entry point for the producer thread.
1.533 +//
1.534 + {
1.535 +
1.536 + testSvr.Title();
1.537 + testSvr.Start(_L("Create CActiveScheduler"));
1.538 + CMyActiveScheduler* pR=new CMyActiveScheduler;
1.539 + testSvr(pR!=NULL);
1.540 + CActiveScheduler::Install(pR);
1.541 +//
1.542 + testSvr.Next(_L("Create CMyServer"));
1.543 + CMyServer* pS=CMyServer::New(0);
1.544 + testSvr(pS!=NULL);
1.545 +//
1.546 + testSvr.Next(_L("Start CMyServer"));
1.547 + TInt r=pS->Start(KServerName);
1.548 + testSvr(r==KErrNone);
1.549 +//
1.550 + testSvr.Next(_L("Signal to client that we have started"));
1.551 + client.Signal();
1.552 +//
1.553 + testSvr.Next(_L("Start CActiveScheduler"));
1.554 + CActiveScheduler::Start();
1.555 +//
1.556 + testSvr.Next(_L("Exit server"));
1.557 + delete pS;
1.558 + testSvr.Close();
1.559 + return(KErrNone);
1.560 + }
1.561 +
1.562 +TInt speedyThreadEntryPoint(TAny* aDisplay)
1.563 +//
1.564 +// The entry point for the speed test thread.
1.565 +//
1.566 + {
1.567 +
1.568 + RDisplay& t=*(RDisplay*)aDisplay;
1.569 + TInt r=t.Test();
1.570 + testSpeedy(r==KErrNone);
1.571 + speedCount=0;
1.572 + client.Signal();
1.573 + while ((r=t.Test())==KErrNone)
1.574 + speedCount++;
1.575 + testSpeedy(r==KErrServerTerminated);
1.576 + return(KErrNone);
1.577 + }
1.578 +
1.579 +TInt RunPanicThread(RThread& aThread)
1.580 + {
1.581 + TRequestStatus s;
1.582 + aThread.Logon(s);
1.583 + TBool jit = User::JustInTime();
1.584 + User::SetJustInTime(EFalse);
1.585 + aThread.Resume();
1.586 + User::WaitForRequest(s);
1.587 + User::SetJustInTime(jit);
1.588 + return s.Int();
1.589 + }
1.590 +
1.591 +TInt RogueThread1(TAny*)
1.592 + {
1.593 + // try to kill the kernel
1.594 + RMutex mutex;
1.595 + TPtrC* p=(TPtrC*)0x30000000;
1.596 + mutex.CreateGlobal(*p,EOwnerProcess); // this should panic the thread
1.597 + return KErrNone;
1.598 + }
1.599 +
1.600 +class RMessageT : public RMessage2
1.601 + {
1.602 +public:
1.603 + RMessageT(TLinAddr anAddr) { iFunction=0; iHandle=(TInt)anAddr; }
1.604 + };
1.605 +
1.606 +TInt RogueThread2(TAny*)
1.607 + {
1.608 + // try to kill the kernel
1.609 + RMessageT m(0x30000000);
1.610 + m.Complete(KErrNone); // this should panic the thread
1.611 + return KErrNone;
1.612 + }
1.613 +
1.614 +TInt RogueThread3(TAny*)
1.615 + {
1.616 + // try to kill the kernel
1.617 + RMessageT m(0x80000000);
1.618 + m.Complete(KErrNone); // this should panic the thread
1.619 + return KErrNone;
1.620 + }
1.621 +
1.622 +TInt RogueThread4(TAny*)
1.623 + {
1.624 + // try to kill the kernel
1.625 + RMessageT m(0x800fff00); // this should be off the end of the kernel heap
1.626 + m.Complete(KErrNone); // this should panic the thread
1.627 + return KErrNone;
1.628 + }
1.629 +
1.630 +void DisplayThreadExitInfo(const RThread& aThread)
1.631 + {
1.632 + TFullName fn=aThread.FullName();
1.633 + TExitType exitType=aThread.ExitType();
1.634 + TInt exitReason=aThread.ExitReason();
1.635 + TBuf<32> exitCat=aThread.ExitCategory();
1.636 + test.Printf(_L("Thread %S exited %d,%d,%S\n"),&fn,exitType,exitReason,&exitCat);
1.637 + }
1.638 +
1.639 +void RogueThreadTest()
1.640 + {
1.641 + RThread thread;
1.642 + TInt r;
1.643 + if (HaveVirtMem())
1.644 + {
1.645 + test.Next(_L("Rogue thread test 1"));
1.646 + r=thread.Create(_L("Rogue1"),RogueThread1,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.647 + test_KErrNone(r);
1.648 + RunPanicThread(thread); // wait for rogue thread to die
1.649 + DisplayThreadExitInfo(thread);
1.650 + test(thread.ExitType()==EExitPanic);
1.651 + test(thread.ExitReason()==ECausedException);
1.652 + thread.Close();
1.653 + }
1.654 +
1.655 + test.Next(_L("Rogue thread test 2"));
1.656 + r=thread.Create(_L("Rogue2"),RogueThread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.657 + test_KErrNone(r);
1.658 + RunPanicThread(thread); // wait for rogue thread to die
1.659 + DisplayThreadExitInfo(thread);
1.660 + test(thread.ExitType()==EExitPanic);
1.661 + test(thread.ExitReason()==EBadMessageHandle);
1.662 + thread.Close();
1.663 +
1.664 + test.Next(_L("Rogue thread test 3"));
1.665 + r=thread.Create(_L("Rogue3"),RogueThread3,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.666 + test_KErrNone(r);
1.667 + RunPanicThread(thread); // wait for rogue thread to die
1.668 + DisplayThreadExitInfo(thread);
1.669 + test(thread.ExitType()==EExitPanic);
1.670 + test(thread.ExitReason()==EBadMessageHandle);
1.671 + thread.Close();
1.672 +
1.673 + test.Next(_L("Rogue thread test 4"));
1.674 + r=thread.Create(_L("Rogue4"),RogueThread4,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.675 + test_KErrNone(r);
1.676 + RunPanicThread(thread); // wait for rogue thread to die
1.677 + DisplayThreadExitInfo(thread);
1.678 + test(thread.ExitType()==EExitPanic);
1.679 + test(thread.ExitReason()==EBadMessageHandle);
1.680 + thread.Close();
1.681 + }
1.682 +
1.683 +TInt SecondClient(TAny* aSession)
1.684 + {
1.685 + RDisplay d;
1.686 + d.SetHandle(TInt(aSession));
1.687 + TInt r=d.Display(_L("Second client"));
1.688 + if (r!=KErrNone)
1.689 + return r;
1.690 + r = d.Echo(0,19,31,83,487);
1.691 + if (r!=19)
1.692 + return -999990;
1.693 + r = d.Echo(1,19,31,83,487);
1.694 + if (r!=31)
1.695 + return -999991;
1.696 + r = d.Echo(2,19,31,83,487);
1.697 + if (r!=83)
1.698 + return -999992;
1.699 + r = d.Echo(3,19,31,83,487);
1.700 + if (r!=487)
1.701 + return -999993;
1.702 + r = d.Echo(4,19,31,83,487);
1.703 + if (r!=620)
1.704 + return -999994;
1.705 + r = d.Echo(5,19,31,83,487);
1.706 + if (r!=245380)
1.707 + return -999995;
1.708 + r=d.Read();
1.709 + if (r!=KErrNone)
1.710 + return r;
1.711 + r=d.Write();
1.712 + if (r!=KErrNone)
1.713 + return r;
1.714 + d.Release();
1.715 + return KErrNone;
1.716 + }
1.717 +
1.718 +TInt ThirdClient(TAny* aSession)
1.719 + {
1.720 + RDisplay d;
1.721 + d.SetHandle(TInt(aSession));
1.722 + TInt r=d.Display(_L("Third client"));
1.723 + if (r!=KErrNone)
1.724 + return r;
1.725 + r=d.Hold();
1.726 + if (r!=KErrNone)
1.727 + return r;
1.728 + r=d.Read();
1.729 + if (r!=KErrNone)
1.730 + return r;
1.731 + r=d.Write();
1.732 + if (r!=KErrNone)
1.733 + return r;
1.734 + return KErrNone;
1.735 + }
1.736 +
1.737 +void TestSecondClient(RSessionBase& aSession)
1.738 + {
1.739 + RThread t;
1.740 + TInt r=t.Create(_L("SecondClient"),SecondClient,0x1000,NULL,(TAny*)aSession.Handle());
1.741 + test_KErrNone(r);
1.742 + TRequestStatus s;
1.743 + t.Logon(s);
1.744 + t.Resume();
1.745 + User::WaitForRequest(s);
1.746 + test_KErrNone(s.Int());
1.747 + t.Close();
1.748 + }
1.749 +
1.750 +void TestThirdClient(RSessionBase& aSession)
1.751 + {
1.752 + RThread t;
1.753 + TInt r=t.Create(_L("ThirdClient"),ThirdClient,0x1000,NULL,(TAny*)aSession.Handle());
1.754 + test_KErrNone(r);
1.755 + TRequestStatus s;
1.756 + t.Logon(s);
1.757 + t.Resume();
1.758 + User::WaitForRequest(s);
1.759 + test_KErrNone(s.Int());
1.760 + t.Close();
1.761 + }
1.762 +
1.763 +TInt FourthClient(TAny* aSession)
1.764 + {
1.765 + RDisplay d;
1.766 + d.SetHandle(TInt(aSession));
1.767 + TInt r=d.Display(_L("Fourth client"));
1.768 + if (r!=KErrNone)
1.769 + return r;
1.770 + d.Close();
1.771 + return KErrNone;
1.772 + }
1.773 +
1.774 +void TestSessionClose()
1.775 + {
1.776 + RDisplay d;
1.777 + TInt r=d.Open();
1.778 + test_KErrNone(r);
1.779 + TRequestStatus msgStat;
1.780 + d.Hold(msgStat);
1.781 + test(msgStat==KRequestPending);
1.782 + RThread t;
1.783 + r=t.Create(_L("FourthClient"),FourthClient,0x1000,NULL,(TAny*)d.Handle());
1.784 + test_KErrNone(r);
1.785 + TRequestStatus s;
1.786 + t.Logon(s);
1.787 + t.Resume();
1.788 + User::WaitForRequest(s);
1.789 + test_KErrNone(s.Int());
1.790 + t.Close();
1.791 + User::After(1000000);
1.792 + test(msgStat==KRequestPending);
1.793 + }
1.794 +
1.795 +TInt FifthClient(TAny* aDisplay)
1.796 + {
1.797 + RDisplay& d=*(RDisplay*)aDisplay;
1.798 + TInt r=d.Open();
1.799 + if (r!=KErrNone)
1.800 + return r;
1.801 + r=d.Display(_L("Fifth client"));
1.802 + if (r!=KErrNone)
1.803 + return r;
1.804 + return KErrNone;
1.805 + }
1.806 +
1.807 +void TestZeroShares()
1.808 + {
1.809 + RDisplay d;
1.810 + d.SetHandle(0);
1.811 + RThread t;
1.812 + TInt r=t.Create(_L("FifthClient"),FifthClient,0x1000,NULL,&d);
1.813 + test_KErrNone(r);
1.814 + TRequestStatus s;
1.815 + t.Logon(s);
1.816 + t.Resume();
1.817 + User::WaitForRequest(s);
1.818 + test_KErrNone(s.Int());
1.819 + test(d.Handle()!=0);
1.820 + t.Close();
1.821 + r=d.Display(_L("Access after last share closed"));
1.822 + test_KErrNone(r);
1.823 + d.Close();
1.824 + }
1.825 +
1.826 +TInt AttachClient1(TAny* aSession)
1.827 + {
1.828 + RDisplay d;
1.829 + d.SetHandle(TInt(aSession));
1.830 + __KHEAP_MARK;
1.831 + TInt r=d.Display(_L("Attach client 1"));
1.832 + __KHEAP_MARKEND; // shouldn't need to allocate memory
1.833 + return r;
1.834 + }
1.835 +
1.836 +TInt AttachClient2(TAny* aSession)
1.837 + {
1.838 + RDisplay d;
1.839 + d.SetHandle(TInt(aSession));
1.840 + TInt r=d.Display(_L("Attach client 2"));
1.841 + if (r!=KErrNone)
1.842 + return r;
1.843 + __KHEAP_MARK;
1.844 + r=d.Display(_L("Attach client 2"));
1.845 + __KHEAP_MARKEND; // check no memory was allocated by message send
1.846 + return r;
1.847 + }
1.848 +
1.849 +void TestAttach(RSessionBase& aSession)
1.850 + {
1.851 + test.Next(_L("Test Attach"));
1.852 + RThread t;
1.853 + TInt r=t.Create(_L("AttachClient1"),AttachClient1,0x1000,NULL,(TAny*)aSession.Handle());
1.854 + test_KErrNone(r);
1.855 + r=RunPanicThread(t); // wait for thread to die
1.856 + test_KErrNone(r);
1.857 + test(t.ExitType()==EExitKill);
1.858 + test_KErrNone(t.ExitReason());
1.859 + t.Close();
1.860 +
1.861 + r=t.Create(_L("AttachClient2"),AttachClient2,0x1000,NULL,(TAny*)aSession.Handle());
1.862 + test_KErrNone(r);
1.863 + TRequestStatus s;
1.864 + t.Logon(s);
1.865 + t.Resume();
1.866 + User::WaitForRequest(s);
1.867 + test_KErrNone(s.Int());
1.868 + test(t.ExitType()==EExitKill);
1.869 + test_KErrNone(t.ExitReason());
1.870 + t.Close();
1.871 + }
1.872 +
1.873 +TInt SixthClient(TAny* aDisplay)
1.874 + {
1.875 + RDisplay& d=*(RDisplay*)aDisplay;
1.876 + TInt r=d.Display(_L("Sixth client"));
1.877 + if (r!=KErrNone)
1.878 + return r;
1.879 + TRequestStatus s;
1.880 + User::WaitForRequest(s);
1.881 + return KErrNone;
1.882 + }
1.883 +
1.884 +TInt SeventhClient(TAny* aDisplay)
1.885 + {
1.886 + RDisplay& d=*(RDisplay*)aDisplay;
1.887 + TInt r=d.Display(_L("Seventh client"));
1.888 + if (r!=KErrNone)
1.889 + return r;
1.890 + TRequestStatus s;
1.891 + User::WaitForRequest(s);
1.892 + return KErrNone;
1.893 + }
1.894 +
1.895 +TInt EighthClient(TAny* aDisplay)
1.896 + {
1.897 + RDisplay& d=*(RDisplay*)aDisplay;
1.898 + TInt r=d.Display(_L("Eighth client"));
1.899 + if (r!=KErrNone)
1.900 + return r;
1.901 + TRequestStatus s;
1.902 + User::WaitForRequest(s);
1.903 + return KErrNone;
1.904 + }
1.905 +
1.906 +TInt NinthClient(TAny* aDisplay)
1.907 + {
1.908 + RDisplay& d=*(RDisplay*)aDisplay;
1.909 + TInt r=d.Display(_L("Ninth client"));
1.910 + if (r!=KErrNone)
1.911 + return r;
1.912 + TRequestStatus s;
1.913 + User::WaitForRequest(s);
1.914 + return KErrNone;
1.915 + }
1.916 +
1.917 +void TestAsync(RDisplay& aD)
1.918 + {
1.919 + TInt ci = aD.CompleteIndex();
1.920 + TRequestStatus s[128];
1.921 + TInt i;
1.922 + TInt r;
1.923 + for (i=0; i<128; ++i)
1.924 + {
1.925 + TInt ord = i ^ 0x55;
1.926 + TInt arg = i + 1;
1.927 + aD.Hold(s[i], ord, arg);
1.928 + if (s[i]==KErrServerBusy)
1.929 + {
1.930 + User::WaitForRequest(s[i]);
1.931 + break;
1.932 + }
1.933 + test(s[i]==KRequestPending);
1.934 + }
1.935 + r = aD.Release();
1.936 + test_KErrNone(r);
1.937 + TInt j;
1.938 + for (j=0; j<128; ++j)
1.939 + {
1.940 + if ( (j^0x55) >= i )
1.941 + continue;
1.942 + TInt code = s[j^0x55].Int();
1.943 + TInt expected = ci ^ ((j^0x55)+1);
1.944 + if (code != expected)
1.945 + {
1.946 + test.Printf(_L("j=%02x i=%02x expected=%08x got=%08x\n"),j,j^0x55,expected,code);
1.947 + test(0);
1.948 + }
1.949 + User::WaitForRequest(s[j^0x55]);
1.950 + ++ci;
1.951 + }
1.952 + }
1.953 +
1.954 +void TestSession(RDisplay& aSess)
1.955 + {
1.956 +//
1.957 + TInt r;
1.958 + test.Next(_L("Test all args passed"));
1.959 + test(aSess.Echo(0,3,5,7,11)==3);
1.960 + test(aSess.Echo(1,3,5,7,11)==5);
1.961 + test(aSess.Echo(2,3,5,7,11)==7);
1.962 + test(aSess.Echo(3,3,5,7,11)==11);
1.963 + test(aSess.Echo(4,3,5,7,11)==26);
1.964 + test(aSess.Echo(5,3,5,7,11)==204);
1.965 +//
1.966 + test.Next(_L("Send to server"));
1.967 + r=aSess.Display(_L("First message"));
1.968 + test_KErrNone(r);
1.969 +//
1.970 + test.Next(_L("Read"));
1.971 + r=aSess.Read();
1.972 + test_KErrNone(r);
1.973 +//
1.974 + test.Next(_L("Write"));
1.975 + r=aSess.Write();
1.976 + test_KErrNone(r);
1.977 +//
1.978 + TestThirdClient(aSess);
1.979 + User::After(1000000);
1.980 + TestSecondClient(aSess);
1.981 + User::After(1000000);
1.982 + TestSessionClose();
1.983 + User::After(1000000);
1.984 + TestZeroShares();
1.985 + User::After(1000000);
1.986 + TestAttach(aSess);
1.987 + User::After(1000000);
1.988 + }
1.989 +
1.990 +void TestUnsharableSession(RDisplay& aSess)
1.991 + {
1.992 +//
1.993 + TInt r;
1.994 + test.Next(_L("Test all args passed"));
1.995 + test(aSess.Echo(0,3,5,7,11)==3);
1.996 + test(aSess.Echo(1,3,5,7,11)==5);
1.997 + test(aSess.Echo(2,3,5,7,11)==7);
1.998 + test(aSess.Echo(3,3,5,7,11)==11);
1.999 + test(aSess.Echo(4,3,5,7,11)==26);
1.1000 + test(aSess.Echo(5,3,5,7,11)==204);
1.1001 +//
1.1002 + test.Next(_L("Send to server"));
1.1003 + r=aSess.Display(_L("First message"));
1.1004 + test_KErrNone(r);
1.1005 +//
1.1006 + test.Next(_L("Read"));
1.1007 + r=aSess.Read();
1.1008 + test_KErrNone(r);
1.1009 +//
1.1010 + test.Next(_L("Write"));
1.1011 + r=aSess.Write();
1.1012 + test_KErrNone(r);
1.1013 +//
1.1014 + TInt h = aSess.Handle();
1.1015 + test.Printf(_L("HANDLE %08x\n"), h);
1.1016 + test((h & KHandleFlagLocal)!=0);
1.1017 + }
1.1018 +
1.1019 +void TestSessionCreateLLeaving()
1.1020 + {
1.1021 + SessionCreateLResult=KErrGeneral;
1.1022 +
1.1023 + TInt c=SessionCostructCount;
1.1024 + TInt d=SessionDestructCount;
1.1025 +
1.1026 + RDisplay t;
1.1027 + TInt r = t.Open();
1.1028 + test(r==SessionCreateLResult);
1.1029 +
1.1030 + test(SessionCostructCount==c+1);
1.1031 + test(SessionDestructCount==d+1);
1.1032 +
1.1033 + SessionCreateLResult=KErrNone;
1.1034 + }
1.1035 +
1.1036 +GLDEF_C TInt E32Main()
1.1037 +//
1.1038 +// Test timers.
1.1039 +//
1.1040 + {
1.1041 +
1.1042 + test.Title();
1.1043 + test.Start(_L("Creating client semaphore"));
1.1044 + TInt r=client.CreateLocal(0);
1.1045 + test_KErrNone(r);
1.1046 +//
1.1047 + test.Next(_L("Creating server thread"));
1.1048 + RThread server;
1.1049 + r=server.Create(_L("Server"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
1.1050 + test_KErrNone(r);
1.1051 + server.SetPriority(EPriorityMore);
1.1052 +//
1.1053 + test.Next(_L("Resume server thread"));
1.1054 + server.Resume();
1.1055 + test(ETrue);
1.1056 +//
1.1057 + test.Next(_L("Wait for server to start"));
1.1058 + client.Wait();
1.1059 +//
1.1060 + test.Next(_L("Connect to server"));
1.1061 + RDisplay t;
1.1062 + r = t.OpenNoAsync();
1.1063 + test_KErrNone(r);
1.1064 + test.Next(_L("Send to server"));
1.1065 + r=t.Display(_L("AsyncMsg"));
1.1066 + test_KErrNone(r);
1.1067 + TRequestStatus s0;
1.1068 + t.Hold(s0);
1.1069 + test(s0==KErrServerBusy);
1.1070 + t.Close();
1.1071 +//
1.1072 + test.Next(_L("Test Session::CreateL leaving"));
1.1073 + TestSessionCreateLLeaving();
1.1074 +//
1.1075 + test.Next(_L("Async fixed pool"));
1.1076 + r = t.Open();
1.1077 + test_KErrNone(r);
1.1078 + TestAsync(t);
1.1079 + TestAsync(t);
1.1080 + t.Close();
1.1081 + test.Next(_L("Async global pool"));
1.1082 + r = t.OpenDynamic();
1.1083 + test_KErrNone(r);
1.1084 + TestAsync(t);
1.1085 + TestAsync(t);
1.1086 + t.Close();
1.1087 +//
1.1088 + r=t.Open();
1.1089 + test_KErrNone(r);
1.1090 +//
1.1091 + TestSession(t);
1.1092 +//
1.1093 + RDisplay tt;
1.1094 + r = tt.OpenS();
1.1095 + test.Printf(_L("OpenS -> %d\n"),r);
1.1096 + test_KErrNone(r);
1.1097 + TestSession(tt);
1.1098 + tt.Close();
1.1099 +//
1.1100 + r = tt.OpenGS();
1.1101 + test.Printf(_L("OpenGS -> %d\n"),r);
1.1102 + test(r==KErrPermissionDenied);
1.1103 + tt.Close();
1.1104 +//
1.1105 + r = tt.OpenUS();
1.1106 + test.Printf(_L("OpenUS -> %d\n"),r);
1.1107 + test_KErrNone(r);
1.1108 + TestUnsharableSession(tt);
1.1109 + tt.Close();
1.1110 +//
1.1111 + test.Next(_L("Starting speedy client"));
1.1112 + RThread speedy;
1.1113 + TRequestStatus speedyStat;
1.1114 + r=speedy.Create(_L("Speedy"),speedyThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,&t);
1.1115 + test_KErrNone(r);
1.1116 + speedy.Logon(speedyStat);
1.1117 + RThread t1;
1.1118 + RThread t2;
1.1119 + RThread t3;
1.1120 + RThread t4;
1.1121 + TRequestStatus s1;
1.1122 + TRequestStatus s2;
1.1123 + TRequestStatus s3;
1.1124 + TRequestStatus s4;
1.1125 + r=t1.Create(_L("SixthClient"),SixthClient,0x1000,NULL,&t);
1.1126 + test_KErrNone(r);
1.1127 + t1.Logon(s1);
1.1128 + r=t2.Create(_L("SeventhClient"),SeventhClient,0x1000,NULL,&t);
1.1129 + test_KErrNone(r);
1.1130 + t2.Logon(s2);
1.1131 + r=t3.Create(_L("EighthClient"),EighthClient,0x1000,NULL,&t);
1.1132 + test_KErrNone(r);
1.1133 + t3.Logon(s3);
1.1134 + r=t4.Create(_L("NinthClient"),NinthClient,0x1000,NULL,&t);
1.1135 + test_KErrNone(r);
1.1136 + t4.Logon(s4);
1.1137 + t1.Resume();
1.1138 + t2.Resume();
1.1139 + t3.Resume();
1.1140 + t4.Resume();
1.1141 + User::After(1000000);
1.1142 +//
1.1143 + test.Next(_L("Wait for speedy to start"));
1.1144 + speedy.SetPriority(EPriorityNormal);
1.1145 + RThread().SetPriority(EPriorityMuchMore);
1.1146 + speedy.Resume();
1.1147 + client.Wait();
1.1148 +//
1.1149 + test.Printf(_L("Starting speed test...\n"));
1.1150 + User::After(300000);
1.1151 + TInt b=speedCount;
1.1152 + User::After(3000000);
1.1153 + TInt n=speedCount;
1.1154 + test.Printf(_L("Count = %d in 1 second\n"),(n-b)/3);
1.1155 +//
1.1156 + test.Next(_L("Stop server"));
1.1157 + r=t.Stop();
1.1158 + test_KErrNone(r);
1.1159 + User::After(0); // Allow the speed client to die
1.1160 +//
1.1161 + test.Next(_L("Close extra threads"));
1.1162 + t1.Kill(0);
1.1163 + User::WaitForRequest(s1);
1.1164 + test(t1.ExitType()==EExitKill && s1==KErrNone);
1.1165 + t2.Kill(0);
1.1166 + User::WaitForRequest(s2);
1.1167 + test(t2.ExitType()==EExitKill && s2==KErrNone);
1.1168 + t3.Kill(0);
1.1169 + User::WaitForRequest(s3);
1.1170 + test(t3.ExitType()==EExitKill && s3==KErrNone);
1.1171 + t4.Kill(0);
1.1172 + User::WaitForRequest(s4);
1.1173 + test(t4.ExitType()==EExitKill && s4==KErrNone);
1.1174 + User::WaitForRequest(speedyStat);
1.1175 + test(speedy.ExitType()==EExitKill && speedyStat==KErrNone);
1.1176 +//
1.1177 + test.Next(_L("Close all"));
1.1178 + t1.Close();
1.1179 + t2.Close();
1.1180 + t3.Close();
1.1181 + t4.Close();
1.1182 + speedy.Close();
1.1183 + server.Close();
1.1184 + client.Close();
1.1185 +//
1.1186 + test.Next(_L("Close connection"));
1.1187 + t.Close();
1.1188 +//
1.1189 + RogueThreadTest();
1.1190 +//
1.1191 + test.End();
1.1192 + return(0);
1.1193 + }
1.1194 +