sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\thread\t_killer.cpp sl@0: // Derived from T_MESSGE, tests threads killing each other, not cleaning up etc. sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: const TInt KHeapMinSize=0x1000; sl@0: const TInt KHeapMaxSize=0x1000; sl@0: sl@0: class CTestServer : public CServer2 sl@0: { sl@0: public: sl@0: IMPORT_C CTestServer(TInt aPriority); sl@0: enum TPanicType{ sl@0: EInt0Error=1, EInt1Error, EInt2Error, EInt3Error, sl@0: EPtr0Error, EPtr1Error, EPtr2Error, EPtr3Error, sl@0: ECreateNameError, ENewSessionError, sl@0: EClientError, EWatcherError, EKilled sl@0: }; sl@0: static void Panic(TPanicType aReason); sl@0: protected: sl@0: //override the pure virtual functions: sl@0: IMPORT_C virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2 &) const; sl@0: }; sl@0: sl@0: sl@0: class CTestSession : public CSession2 sl@0: { sl@0: public: sl@0: enum {EStop,ETestInt,ETestPtr,ETestClient,ETestComplete,ETestPtrComplete,ETestCompletePanic,ETestOtherSession,ETestCompleteAfter}; sl@0: //Override pure virtual sl@0: IMPORT_C virtual void ServiceL(const RMessage2& aMessage); sl@0: private: sl@0: void TestInt(const RMessage2& aMessage); sl@0: void TestPtr(const RMessage2& aMessage); sl@0: void TestClient(const RMessage2& aMessage); sl@0: void TestComplete(const RMessage2& aMessage); sl@0: void TestPtrComplete(const RMessage2& aMessage); sl@0: void TestCompletePanic(); sl@0: // sl@0: TInt count1;//initially ==0 sl@0: RMessage2 messages[5];//Used in TestComplete() sl@0: // sl@0: TInt count2;//initially ==0 sl@0: RMessagePtr2 messagePtrs[5];//User in TestPtrComplete() sl@0: }; sl@0: sl@0: sl@0: class CMyActiveScheduler : public CActiveScheduler sl@0: { sl@0: public: sl@0: virtual void Error(TInt anError) const; //override pure virtual error function sl@0: }; sl@0: sl@0: sl@0: class RSession : public RSessionBase sl@0: { sl@0: public: sl@0: TInt PublicSendReceive(TInt aFunction, const TIpcArgs& aArgs) sl@0: { sl@0: return (SendReceive(aFunction, aArgs)); sl@0: } sl@0: void PublicSendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) sl@0: { sl@0: SendReceive(aFunction, aArgs, aStatus); sl@0: } sl@0: TInt PublicCreateSession(const TDesC& aServer,TInt aMessageSlots) sl@0: { sl@0: return (CreateSession(aServer,User::Version(),aMessageSlots)); sl@0: } sl@0: }; sl@0: sl@0: //========================================================================= sl@0: sl@0: // CTestServer functions sl@0: sl@0: CTestServer::CTestServer(TInt aPriority) sl@0: // sl@0: // Constructor - sets name sl@0: // sl@0: : CServer2(aPriority) sl@0: {} sl@0: sl@0: CSession2* CTestServer::NewSessionL(const TVersion& aVersion, const RMessage2 &) const sl@0: // sl@0: // Virtual fn - checks version supported and creates a CTestSession sl@0: // sl@0: { sl@0: TVersion version(KE32MajorVersionNumber,KE32MinorVersionNumber,KE32BuildVersionNumber); sl@0: if (User::QueryVersionSupported(version,aVersion)==EFalse) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: CTestSession* newCTestSession = new CTestSession; sl@0: if (newCTestSession==NULL) sl@0: Panic(ENewSessionError); sl@0: return(newCTestSession); sl@0: } sl@0: sl@0: RThread clientThread, serverThread, killerThread; sl@0: sl@0: void CTestServer::Panic(TPanicType aReason) //static function sl@0: { sl@0: clientThread.Kill(KErrNone); sl@0: User::Panic(_L("CTestServer"),aReason); sl@0: } sl@0: sl@0: // CTestSession funtions sl@0: sl@0: RSession session, otherSession; sl@0: RSemaphore sem; sl@0: sl@0: const TInt KTestInt[] = {-3866,30566,0,200}; sl@0: const TIpcArgs KIpcArgInt(-3866,30566,0,200); sl@0: sl@0: void CTestSession::TestInt(const RMessage2& aMessage) sl@0: // sl@0: // Tests to see that the correct Int0/1/2/3 have been received sl@0: // sl@0: { sl@0: if (aMessage.Int0()!=KTestInt[0]) sl@0: CTestServer::Panic(CTestServer::EInt0Error); sl@0: if (aMessage.Int1()!=KTestInt[1]) sl@0: CTestServer::Panic(CTestServer::EInt1Error); sl@0: if (aMessage.Int2()!=KTestInt[2]) sl@0: CTestServer::Panic(CTestServer::EInt2Error); sl@0: if (aMessage.Int3()!=KTestInt[3]) sl@0: CTestServer::Panic(CTestServer::EInt3Error); sl@0: } sl@0: sl@0: const TAny* KTestPtr[]={&clientThread, &serverThread, &session, &sem}; sl@0: const TIpcArgs KIpcArgPtr(&clientThread, &serverThread, &session, &sem); sl@0: sl@0: void CTestSession::TestPtr(const RMessage2& aMessage) sl@0: // sl@0: // Tests to see that the correct Ptr0/1/2/3 have been received sl@0: // sl@0: { sl@0: if (aMessage.Ptr0()!=KTestPtr[0]) sl@0: CTestServer::Panic(CTestServer::EPtr0Error); sl@0: if (aMessage.Ptr1()!=KTestPtr[1]) sl@0: CTestServer::Panic(CTestServer::EPtr1Error); sl@0: if (aMessage.Ptr2()!=KTestPtr[2]) sl@0: CTestServer::Panic(CTestServer::EPtr2Error); sl@0: if (aMessage.Ptr3()!=KTestPtr[3]) sl@0: CTestServer::Panic(CTestServer::EPtr3Error); sl@0: } sl@0: sl@0: TFullName clientName; sl@0: TInt clientNumber; sl@0: sl@0: void CTestSession::TestClient(const RMessage2& aMessage) sl@0: // sl@0: // Tests Client() sl@0: // sl@0: { sl@0: sl@0: // Under WINS, thread names are not prefixed with the process name sl@0: TFullName n=RProcess().Name(); sl@0: n+=_L("::"); sl@0: n+=clientName; sl@0: sl@0: RThread client; sl@0: TInt r = aMessage.Client(client); sl@0: if (r != KErrNone || client.FullName().CompareF(n)!=0) sl@0: { sl@0: client.Close(); sl@0: clientThread.Kill(0); sl@0: CTestServer::Panic(CTestServer::EClientError); sl@0: } sl@0: client.Close(); sl@0: } sl@0: sl@0: void CTestSession::TestComplete(const RMessage2& aMessage) sl@0: // sl@0: // Stores messages up then Completes in reverse order sl@0: // sl@0: { sl@0: messages[count1] = aMessage; sl@0: if (++count1==5) sl@0: for(count1=4; count1>=0; count1--) sl@0: messages[count1].Complete(5-count1); //Complete with different 'error messages' sl@0: } sl@0: sl@0: void CTestSession::TestPtrComplete(const RMessage2& aMessage) sl@0: // sl@0: // Stores messages up as RMessagePtrs then Completes in reverse order sl@0: // Also tests RMessage2::MessagePtr() sl@0: // sl@0: { sl@0: messagePtrs[count2] = aMessage; sl@0: if (++count2==5) sl@0: for(count2=4; count2>=0; count2--) sl@0: messagePtrs[count2].Complete(10-count2*2); sl@0: } sl@0: sl@0: void CTestSession::ServiceL(const RMessage2& aMessage) sl@0: // sl@0: // Virtual message-handler sl@0: // sl@0: { sl@0: TInt r=KErrNone; sl@0: switch (aMessage.Function()) sl@0: { sl@0: case EStop: sl@0: CActiveScheduler::Stop(); sl@0: break; sl@0: case ETestInt: sl@0: TestInt(aMessage); sl@0: break; sl@0: case ETestPtr: sl@0: TestPtr(aMessage); sl@0: break; sl@0: case ETestClient: sl@0: TestClient(aMessage); sl@0: break; sl@0: case ETestComplete: sl@0: TestComplete(aMessage); sl@0: return; sl@0: case ETestPtrComplete: sl@0: TestPtrComplete(aMessage); sl@0: return; sl@0: case ETestCompletePanic: sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case ETestOtherSession: sl@0: break; sl@0: case ETestCompleteAfter: sl@0: User::After(7000000); sl@0: break; sl@0: default: sl@0: r=KErrNotSupported; sl@0: sl@0: } sl@0: aMessage.Complete(r); sl@0: sl@0: } sl@0: sl@0: void CMyActiveScheduler::Error(TInt anError) const sl@0: // sl@0: // Virtual error handler sl@0: // sl@0: { sl@0: User::Panic(_L("CMyActiveScheduer::Error"), anError); sl@0: } sl@0: sl@0: LOCAL_D TInt64 TheSeed; sl@0: GLDEF_C TInt Random(TInt aRange) sl@0: { sl@0: return (Math::Rand(TheSeed)>>11)%aRange; sl@0: } sl@0: sl@0: TInt KillerThread(TAny*) sl@0: // sl@0: // Wait a random time and then kill the client thread sl@0: // sl@0: { sl@0: RTest test(_L("T_KILLER...Killer")); sl@0: TRequestStatus clientStatus; sl@0: TInt delay=0; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Logon to client")); sl@0: clientThread.Logon(clientStatus); sl@0: test.Next(_L("Delay....")); sl@0: for (;;) sl@0: { sl@0: User::After(1000); sl@0: delay++; sl@0: if (clientStatus!=KRequestPending) sl@0: return KErrNone; // client has already finished sl@0: if (Random(1000)<1) sl@0: break; // Time to die! sl@0: } sl@0: test.Printf(_L("Kill client after %d ms\n"), delay); sl@0: clientThread.Kill(CTestServer::EKilled); sl@0: sl@0: test.Close(); // close console immediately sl@0: // test.End(); // "Press ENTER to exit" sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt ClientThread(TAny* aPtr) sl@0: // sl@0: // Passed as the first client thread - signals the server to do several tests sl@0: // sl@0: { sl@0: RTest test(_L("T_KILLER...client")); sl@0: TInt repeat = (TInt)aPtr; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Client thread")); sl@0: sl@0: do sl@0: { sl@0: test.Next(_L("Client loop")); sl@0: test.Start(_L("Create Session")); sl@0: TInt r=session.PublicCreateSession(_L("CTestServer"),5); sl@0: if (r!=KErrNone) sl@0: User::Panic(_L("CreateSessn failure"),r); sl@0: sl@0: test.Next(_L("Signal to test Int0/1/2/3()")); sl@0: r=session.PublicSendReceive(CTestSession::ETestInt, KIpcArgInt); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Signal to test Ptr0/1/2/3()")); sl@0: r=session.PublicSendReceive(CTestSession::ETestPtr, KIpcArgPtr); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Signal to test Client()")); sl@0: r=session.PublicSendReceive(CTestSession::ETestClient, TIpcArgs()); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Test RMessage2::Complete()")); sl@0: TRequestStatus stat[7]; sl@0: for (r=0;r<4;r++) sl@0: { sl@0: session.PublicSendReceive(CTestSession::ETestComplete, TIpcArgs(), stat[r]); sl@0: test(stat[r]==KRequestPending); sl@0: } sl@0: session.PublicSendReceive(CTestSession::ETestComplete, TIpcArgs(), stat[4]); sl@0: User::WaitForRequest(stat[0]); sl@0: for (r=0;r<5;r++) sl@0: test(stat[r]==5-r); //Test the 'error messages' set by Complete() sl@0: test.Next(_L("Test RMessagePtr2::Complete()")); sl@0: for (r=0;r<4;r++) sl@0: { sl@0: session.PublicSendReceive(CTestSession::ETestPtrComplete, TIpcArgs(), stat[r]); sl@0: test(stat[r]==KRequestPending); sl@0: } sl@0: session.PublicSendReceive(CTestSession::ETestPtrComplete, TIpcArgs(), stat[4]); sl@0: User::WaitForRequest(stat[0]); sl@0: for (r=0;r<5;r++) sl@0: test(stat[r]==10-r*2); sl@0: sl@0: test.Next(_L("Try another session")); sl@0: r=otherSession.PublicCreateSession(_L("CTestServer"),5); sl@0: test(r==KErrNone); sl@0: sl@0: r=otherSession.PublicSendReceive(CTestSession::ETestOtherSession, TIpcArgs()); sl@0: test(r==KErrNone); sl@0: sl@0: // test.Next(_L("Try to disconnect")); sl@0: // r=session.PublicSendReceive(RMessage2::EDisConnect,NULL);//Panics user sl@0: // test(r==KErrNone); sl@0: sl@0: test.Next(_L("Saturate server")); sl@0: for(r=0;r<7;r++) sl@0: { sl@0: test.Printf(_L("Send %d\r"),r); sl@0: session.PublicSendReceive(CTestSession::ETestCompleteAfter,TIpcArgs(),stat[r]); sl@0: if (r<5) sl@0: test(stat[r]==KRequestPending); sl@0: else sl@0: test(stat[r]==KErrServerBusy); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: for(r=0;r<5;r++) sl@0: { sl@0: test.Printf(_L("Wait %d\r"),r); sl@0: User::WaitForRequest(stat[r]); sl@0: test(stat[r]==KErrNone); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: test.End(); sl@0: } sl@0: while (--repeat > 0); sl@0: test.Start(_L("Signal to stop ActiveScheduler")); sl@0: session.PublicSendReceive(CTestSession::EStop, TIpcArgs()); sl@0: test.Close(); sl@0: sl@0: return (KErrNone); sl@0: } sl@0: sl@0: TInt ServerThread(TAny*) sl@0: // sl@0: // Passed as the server thread in 2 tests - sets up and runs CTestServer sl@0: // sl@0: { sl@0: RTest test(_L("T_KILLER...server")); sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Create and install ActiveScheduler")); sl@0: CMyActiveScheduler* pScheduler = new CMyActiveScheduler; sl@0: if (pScheduler==NULL) sl@0: { sl@0: clientThread.Kill(0); sl@0: User::Panic(_L("CreateSched failure"),KErrNoMemory); sl@0: } sl@0: sl@0: CActiveScheduler::Install(pScheduler); sl@0: sl@0: test.Next(_L("Creating and starting Server")); sl@0: CTestServer* pServer = new CTestServer(0); sl@0: if (pServer==NULL) sl@0: { sl@0: clientThread.Kill(0); sl@0: User::Panic(_L("CreateServr failure"),KErrNoMemory); sl@0: } sl@0: sl@0: TInt r=pServer->Start(_L("CTestServer"));//Starting a CServer2 also Adds it to the ActiveScheduler sl@0: if (r!=KErrNone) sl@0: { sl@0: clientThread.Kill(0); sl@0: User::Panic(_L("StartServr failure"),r); sl@0: } sl@0: sl@0: sl@0: test.Next(_L("Start ActiveScheduler and signal to client")); sl@0: test.Printf(_L(" There might be something going on beneath this window")); sl@0: sem.Signal(); sl@0: CActiveScheduler::Start(); sl@0: test.Next(_L("Destroy ActiveScheduler")); sl@0: delete pScheduler; sl@0: delete pServer; sl@0: sl@0: test.Close(); sl@0: sl@0: return (KErrNone); sl@0: } sl@0: sl@0: const TInt KTestPanic = 14849; sl@0: sl@0: TInt PanicTestThread (TAny*) sl@0: // sl@0: // Passed as a thread entry - just calls RMessage2::Panic() sl@0: // sl@0: { sl@0: RMessage2 message; sl@0: message.Panic(_L("Testing Panic"),KTestPanic); sl@0: return(KErrNone); sl@0: } sl@0: sl@0: RTest test(_L("Main T_KILLER test")); sl@0: sl@0: TInt CompletePanicClientThread (TAny*) sl@0: // sl@0: // Passed as the second client thread entry - signals to server to call Complete() twice sl@0: // sl@0: { sl@0: sem.Wait(); sl@0: sl@0: TInt r=session.PublicCreateSession(_L("CTestServer"),1); sl@0: test(r==KErrNone); sl@0: sl@0: r=session.PublicSendReceive(CTestSession::ETestCompletePanic, TIpcArgs()); sl@0: test(r==KErrNone); sl@0: sl@0: session.PublicSendReceive(CTestSession::EStop, TIpcArgs());//panic should occur before this is serviced sl@0: return(KErrNone); sl@0: } sl@0: sl@0: void SimpleRMessage() sl@0: // sl@0: // Simple RMessage2 Tests - constructors and assignment sl@0: // sl@0: { sl@0: sl@0: test.Start(_L("Default constructor")); sl@0: RMessage2 message1; sl@0: sl@0: test.Next(_L("Copy constructor")); sl@0: RMessage2 message2(message1); sl@0: test(message1.Function()==message2.Function()); sl@0: test(message1.Int0()==message2.Int0()); sl@0: test(message1.Int1()==message2.Int1()); sl@0: test(message1.Int2()==message2.Int2()); sl@0: test(message1.Int3()==message2.Int3()); sl@0: RThread client1; sl@0: test(message1.Client(client1) == KErrNone); sl@0: RThread client2; sl@0: test(message2.Client(client2) == KErrNone); sl@0: test(client1.Handle()==client2.Handle()); sl@0: client2.Close(); sl@0: sl@0: test.Next(_L("Assignment operator")); sl@0: RMessage2 message3(*(RMessage2*) SimpleRMessage);// Pass some rubbish so message3 is definitely != message1 sl@0: message3=message1; sl@0: test(message1.Function()==message3.Function()); sl@0: test(message1.Int0()==message3.Int0()); sl@0: test(message1.Int1()==message3.Int1()); sl@0: test(message1.Int2()==message3.Int2()); sl@0: test(message1.Int3()==message3.Int3()); sl@0: RThread client3; sl@0: test(message3.Client(client3) == KErrNone); sl@0: test(client1.Handle()==client3.Handle()); sl@0: client3.Close(); sl@0: client1.Close(); sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: TInt err; sl@0: sl@0: #ifdef __WINS__ sl@0: User::SetDebugMask(0xa04); // KSERVER+KTHREAD+KLOGON sl@0: #endif sl@0: test.Title(); sl@0: sl@0: test.Next(_L("Sending messages between two threads")); sl@0: TRequestStatus clientStat,killerStat,serverStat; sl@0: TInt exitType; sl@0: sl@0: test.Start(_L("Create and start the server")); sl@0: sem.CreateLocal(0); sl@0: serverThread.Create(_L("Server Thread"),ServerThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,NULL); sl@0: serverThread.Logon(serverStat); sl@0: serverThread.Resume(); sl@0: sem.Wait(); sl@0: sl@0: for (TInt i=0; serverStat==KRequestPending && i<100; i++) sl@0: { sl@0: test.Next(_L("Run and kill a client")); sl@0: clientName.Format(_L("Client Thread %d"),++clientNumber); sl@0: sl@0: test.Start(_L("Create client and killer threads")); sl@0: err=clientThread.Create(clientName,ClientThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,(TAny *)3); sl@0: if (err) sl@0: test.Panic(_L("!!clientThread .Create failed"), err); sl@0: err=killerThread.Create(_L("Killer Thread"),KillerThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,NULL); sl@0: if (err) sl@0: test.Panic(_L("!!killerThread .Create failed"), err); sl@0: sl@0: test.Next(_L("Logon to the threads")); sl@0: clientThread.Logon(clientStat); sl@0: killerThread.Logon(killerStat); sl@0: sl@0: test.Next(_L("Start the threads")); sl@0: clientThread.Resume(); sl@0: killerThread.Resume(); sl@0: sl@0: test.Next(_L("Wait for the client to stop")); sl@0: User::WaitForRequest(clientStat); sl@0: test.Next(_L("Wait for the killer to stop")); sl@0: User::WaitForRequest(killerStat); sl@0: exitType=clientThread.ExitType(); sl@0: switch (exitType) sl@0: { sl@0: case EExitKill: sl@0: test.Printf(_L(" Client thread killed\n")); sl@0: break; sl@0: case EExitTerminate: sl@0: test.Printf(_L("!!Client thread terminated:")); sl@0: test.Panic(clientThread.ExitCategory(), clientThread.ExitReason()); sl@0: case EExitPanic: sl@0: test.Printf(_L("!!Client thread panicked:")); sl@0: test.Panic(clientThread.ExitCategory(), clientThread.ExitReason()); sl@0: default: sl@0: test.Panic(_L("!!Client thread did something bizarre"), clientThread.ExitReason()); sl@0: } sl@0: exitType=killerThread.ExitType(); sl@0: switch (exitType) sl@0: { sl@0: case EExitKill: sl@0: test.Printf(_L(" Killer thread killed\n")); sl@0: break; sl@0: case EExitTerminate: sl@0: test.Printf(_L("!!Killer thread terminated:")); sl@0: test.Panic(killerThread.ExitCategory(), killerThread.ExitReason()); sl@0: case EExitPanic: sl@0: test.Printf(_L("!!Killer thread panicked:")); sl@0: test.Panic(killerThread.ExitCategory(), killerThread.ExitReason()); sl@0: // sl@0: // To catch a panic put a breakpoint in User::Panic() (in UCDT\UC_UNC.CPP). sl@0: // sl@0: default: sl@0: test.Panic(_L("!!Killer thread did something bizarre"), killerThread.ExitReason()); sl@0: } sl@0: test.Next(_L("Close the threads")); sl@0: clientThread.Close(); sl@0: killerThread.Close(); sl@0: // test.Next(_L("Pause for 1 second")); sl@0: // User::After(1000000); sl@0: test.End(); sl@0: } sl@0: test.Next(_L("Close the server thread")); sl@0: serverThread.Kill(0); // in case we got through the 100 iterations without killing it sl@0: User::WaitForRequest(serverStat); sl@0: exitType=serverThread.ExitType(); sl@0: switch (exitType) sl@0: { sl@0: case EExitKill: sl@0: test.Printf(_L(" Server thread killed\n")); sl@0: break; sl@0: case EExitTerminate: sl@0: test.Printf(_L("!!Server thread terminated:")); sl@0: test.Panic(serverThread.ExitCategory(), serverThread.ExitReason()); sl@0: case EExitPanic: sl@0: test.Printf(_L("!!Server thread panicked:")); sl@0: test.Panic(serverThread.ExitCategory(), serverThread.ExitReason()); sl@0: // sl@0: // To catch a panic put a breakpoint in User::Panic() (in UCDT\UC_UNC.CPP). sl@0: // sl@0: default: sl@0: test.Panic(_L("!!Server thread did something bizarre"), serverThread.ExitReason()); sl@0: } sl@0: serverThread.Close(); sl@0: test.End(); sl@0: sl@0: test.Next(_L("The Panic() function")); sl@0: RThread panicThread; sl@0: panicThread.Create(_L("Panic Test Thread"),PanicTestThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,NULL); sl@0: TRequestStatus stat; sl@0: panicThread.Logon(stat); sl@0: // don't want just in time debugging as we trap panics sl@0: TBool justInTime=User::JustInTime(); sl@0: User::SetJustInTime(EFalse); sl@0: panicThread.Resume(); sl@0: User::WaitForRequest(stat); sl@0: test(panicThread.ExitType()==EExitPanic); sl@0: test(panicThread.ExitCategory().Compare(_L("Testing Panic"))==0); sl@0: test(panicThread.ExitReason()==KTestPanic); sl@0: panicThread.Close(); //If this Close() is missed out Wins build 48 throws a wobbler when we next connect a server sl@0: sl@0: sl@0: test.Next(_L("Check it Panics if you try to Complete a message twice")); sl@0: test.Start(_L("Create client and server threads")); sl@0: clientThread.Create(_L("Client Thread"),CompletePanicClientThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,NULL); sl@0: serverThread.Create(_L("Server Thread"),ServerThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize,NULL); sl@0: sl@0: test.Next(_L("Logon to the threads")); sl@0: clientThread.Logon(clientStat); sl@0: serverThread.Logon(serverStat); sl@0: sl@0: test.Next(_L("Start the threads")); sl@0: sem.CreateLocal(0); sl@0: clientThread.Resume(); sl@0: serverThread.Resume(); sl@0: sl@0: test.Next(_L("Wait for the threads to stop")); sl@0: User::WaitForRequest(clientStat); sl@0: User::WaitForRequest(serverStat); sl@0: test.Next(_L("Check the exit categories")); sl@0: test(clientThread.ExitType()==EExitKill); sl@0: test(clientThread.ExitCategory().Compare(_L("Kill"))==0); sl@0: test(clientThread.ExitReason()==KErrNone); sl@0: sl@0: test(serverThread.ExitType()==EExitPanic); sl@0: test(serverThread.ExitCategory().Compare(_L("USER"))==0); sl@0: test(serverThread.ExitReason()==ETMesCompletion); sl@0: sl@0: User::SetJustInTime(justInTime); sl@0: sl@0: test.Next(_L("Close the threads")); sl@0: clientThread.Close(); sl@0: serverThread.Close(); sl@0: test.End(); sl@0: sl@0: test.End(); sl@0: sl@0: return (KErrNone); sl@0: } sl@0: