diff -r 000000000000 -r a41df078684a kerneltest/e32test/thread/t_thread2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/thread/t_thread2.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,247 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\thread\t_thread2.cpp +// More tests the RThread class (T_THREAD was getting too big) +// Overview: +// Tests the RThread class +// API Information: +// RThread +// Details: +// - Test running a thread that suspends itself. This activity has +// deadlocked the Emulator in the past. +// - Test a server panicking a thread in another process that's already exited +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#define __E32TEST_EXTENSION__ +#include +#include +#include + +const TInt KHeapSize=0x200; + +_LIT(KMyName, "T_THREAD2"); + +LOCAL_D RTest test(KMyName); + +LOCAL_C TInt SuspendThread(TAny*) + { + + RThread().Suspend(); + return(KErrNone); + } + + +LOCAL_D void TestSelfSuspend(TOwnerType anOwnerType) +// +// Test running a thread that suspends itself. This activity has +// deadlocked the Emulator in the past +// + { + + RThread suspendThread; + TInt r; + TRequestStatus s; + TInt jit=User::JustInTime(); + test.Start(_L("Test running a thread which suspends itself")); + test.Next(_L("Create the thread")); + r=suspendThread.Create(KNullDesC,SuspendThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)NULL,anOwnerType); + test(r==KErrNone); + suspendThread.Logon(s); + suspendThread.Resume(); + test.Next(_L("Wait a second")); + User::After(1000000); + User::SetJustInTime(EFalse); + suspendThread.Panic(_L("FEDCBA9876543210fedcba"),999); + User::WaitForRequest(s); + User::SetJustInTime(jit); + test(suspendThread.ExitType()==EExitPanic); + test(suspendThread.ExitReason()==999); + test(suspendThread.ExitCategory()==_L("FEDCBA9876543210")); + CLOSE_AND_WAIT(suspendThread); + test.End(); + } + + +_LIT(KServerName,"MyServer"); + +RSemaphore TheSemaphore; + +class CMySession : public CSession2 + { +public: + CMySession(); + virtual void ServiceL(const RMessage2& aMessage); + }; + +class CMyServer : public CServer2 + { +public: + CMyServer(); + virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; + }; + +class RSession : public RSessionBase + { +public: + TInt Open(); + void Test(TRequestStatus& aStatus); + }; + +CMySession::CMySession() + { + } + +CMyServer::CMyServer() : + CServer2(0) + { + } + +CSession2* CMyServer::NewSessionL(const TVersion&, const RMessage2&) const + { + RDebug::Printf("Server: create session"); + return new (ELeave) CMySession; + } + +void CMySession::ServiceL(const RMessage2& aMessage) + { + RDebug::Printf("Server: receive message"); + TheSemaphore.Wait(); + RDebug::Printf("Server: panic client"); + aMessage.Panic(_L("!!!"), 1); + CActiveScheduler::Stop(); + } + +TInt RSession::Open() + { + return CreateSession(KServerName, TVersion()); + } + +void RSession::Test(TRequestStatus& aStatus) + { + RDebug::Printf("Client: send message"); + SendReceive(0, TIpcArgs(), aStatus); + RDebug::Printf("Client: send done"); + } + +TInt ServerThread(TAny*) + { + RDebug::Printf("Server: start"); + + CTrapCleanup* cleanup = CTrapCleanup::New(); + + CActiveScheduler* pR = new CActiveScheduler; + if (pR == NULL) + return KErrNoMemory; + CActiveScheduler::Install(pR); + + CMyServer* pS = new CMyServer; + if (pS == NULL) + return KErrNoMemory; + TInt r = pS->Start(KServerName); + if (r != KErrNone) + return r; + RThread::Rendezvous(KErrNone); + + TRAP(r, CActiveScheduler::Start()); + if (r != KErrNone) + return r; + + delete pS; + delete pR; + delete cleanup; + + RDebug::Printf("Server: exit"); + return KErrNone; + } + +TInt ClientProcess() + { + RDebug::Printf("Client: open session"); + RSession session; + session.Open(); + TRequestStatus status; + RDebug::Printf("Client: send request"); + session.Test(status); + RDebug::Printf("Client: exit"); + return KErrNone; + } + +void TestServerPanic() + { + TRequestStatus status; + + test_KErrNone(TheSemaphore.CreateLocal(0)); + + RDebug::Printf("Main: start server"); + RThread serverThread; + test_KErrNone(serverThread.Create(_L("server"), ServerThread, 4096, NULL, NULL)); + serverThread.Rendezvous(status); + serverThread.Resume(); + User::WaitForRequest(status); + test_KErrNone(status.Int()); + + RDebug::Printf("Main: start client"); + RProcess clientProcess; + test_KErrNone(clientProcess.Create(KMyName, _L("client"))); + clientProcess.Resume(); + clientProcess.Logon(status); + User::WaitForRequest(status); + test_KErrNone(clientProcess.ExitReason()); + test_Equal(EExitKill, clientProcess.ExitType()); + + RDebug::Printf("Main: kick server"); + TheSemaphore.Signal(); + + RDebug::Printf("Main: wait for server to exit"); + serverThread.Logon(status); + User::WaitForRequest(status); + test_KErrNone(serverThread.ExitReason()); + test_Equal(EExitKill, serverThread.ExitType()); + + User::After(1); + RDebug::Printf("Main: exit"); + } + + +GLDEF_C TInt E32Main() +// +// Main +// + { + + if (User::CommandLineLength()) + return ClientProcess(); + + test.Title(); + __UHEAP_MARK; + + test.Start(_L("Test threads")); + + test.Next(_L("Test a thread suspending itself")); + TestSelfSuspend(EOwnerProcess); + TestSelfSuspend(EOwnerThread); + + test.Next(_L("Test a server panicking a thread in another process that's already exited")); + TestServerPanic(); + + test.End(); + __UHEAP_MARKEND; + return(KErrNone); + }