--- /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 <e32test.h>
+#include <e32panic.h>
+#include <e32debug.h>
+
+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);
+ }