kerneltest/e32test/thread/t_thread2.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-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\thread\t_thread2.cpp
       
    15 // More tests the RThread class (T_THREAD was getting too big)
       
    16 // Overview:
       
    17 // Tests the RThread class
       
    18 // API Information:
       
    19 // RThread
       
    20 // Details:
       
    21 // - Test running a thread that suspends itself.  This activity has 
       
    22 // deadlocked the Emulator in the past.
       
    23 // - Test a server panicking a thread in another process that's already exited
       
    24 // Platforms/Drives/Compatibility:
       
    25 // All.
       
    26 // Assumptions/Requirement/Pre-requisites:
       
    27 // Failures and causes:
       
    28 // Base Port information:
       
    29 // 
       
    30 //
       
    31 
       
    32 #define __E32TEST_EXTENSION__
       
    33 #include <e32test.h>
       
    34 #include <e32panic.h>
       
    35 #include <e32debug.h>
       
    36 
       
    37 const TInt KHeapSize=0x200;
       
    38 
       
    39 _LIT(KMyName, "T_THREAD2");
       
    40 
       
    41 LOCAL_D RTest test(KMyName);
       
    42 
       
    43 LOCAL_C TInt SuspendThread(TAny*)
       
    44 	{
       
    45 	
       
    46 	RThread().Suspend();
       
    47 	return(KErrNone);
       
    48 	}
       
    49 
       
    50 
       
    51 LOCAL_D void TestSelfSuspend(TOwnerType anOwnerType)
       
    52 //
       
    53 // Test running a thread that suspends itself.  This activity has 
       
    54 // deadlocked the Emulator in the past
       
    55 //
       
    56 	{
       
    57 
       
    58 	RThread suspendThread;
       
    59 	TInt r;
       
    60 	TRequestStatus s;
       
    61 	TInt jit=User::JustInTime();
       
    62 	test.Start(_L("Test running a thread which suspends itself"));
       
    63 	test.Next(_L("Create the thread"));
       
    64 	r=suspendThread.Create(KNullDesC,SuspendThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)NULL,anOwnerType);
       
    65 	test(r==KErrNone);
       
    66 	suspendThread.Logon(s);
       
    67 	suspendThread.Resume();
       
    68 	test.Next(_L("Wait a second"));
       
    69 	User::After(1000000);
       
    70 	User::SetJustInTime(EFalse);
       
    71 	suspendThread.Panic(_L("FEDCBA9876543210fedcba"),999);
       
    72 	User::WaitForRequest(s);
       
    73 	User::SetJustInTime(jit);
       
    74 	test(suspendThread.ExitType()==EExitPanic);
       
    75 	test(suspendThread.ExitReason()==999);
       
    76 	test(suspendThread.ExitCategory()==_L("FEDCBA9876543210"));
       
    77 	CLOSE_AND_WAIT(suspendThread);
       
    78 	test.End();
       
    79 	}
       
    80 
       
    81 
       
    82 _LIT(KServerName,"MyServer");
       
    83 
       
    84 RSemaphore TheSemaphore;
       
    85 
       
    86 class CMySession : public CSession2
       
    87 	{
       
    88 public:
       
    89 	CMySession();
       
    90 	virtual void ServiceL(const RMessage2& aMessage);
       
    91 	};
       
    92 
       
    93 class CMyServer : public CServer2
       
    94 	{
       
    95 public:
       
    96 	CMyServer();
       
    97 	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
       
    98 	};
       
    99 
       
   100 class RSession : public RSessionBase
       
   101 	{
       
   102 public:
       
   103 	TInt Open();
       
   104 	void Test(TRequestStatus& aStatus);
       
   105 	};
       
   106 
       
   107 CMySession::CMySession()
       
   108 	{
       
   109 	}
       
   110 
       
   111 CMyServer::CMyServer() :
       
   112 	CServer2(0)
       
   113 	{
       
   114 	}
       
   115 
       
   116 CSession2* CMyServer::NewSessionL(const TVersion&, const RMessage2&) const
       
   117 	{
       
   118 	RDebug::Printf("Server: create session");
       
   119 	return new (ELeave) CMySession;
       
   120 	}
       
   121 
       
   122 void CMySession::ServiceL(const RMessage2& aMessage)
       
   123 	{
       
   124 	RDebug::Printf("Server: receive message");
       
   125 	TheSemaphore.Wait();
       
   126 	RDebug::Printf("Server: panic client");
       
   127 	aMessage.Panic(_L("!!!"), 1);
       
   128 	CActiveScheduler::Stop();
       
   129 	}
       
   130 
       
   131 TInt RSession::Open()
       
   132 	{
       
   133 	return CreateSession(KServerName, TVersion());
       
   134 	}
       
   135 
       
   136 void RSession::Test(TRequestStatus& aStatus)
       
   137 	{
       
   138 	RDebug::Printf("Client: send message");
       
   139 	SendReceive(0, TIpcArgs(), aStatus);
       
   140 	RDebug::Printf("Client: send done");
       
   141 	}
       
   142 
       
   143 TInt ServerThread(TAny*)
       
   144 	{
       
   145 	RDebug::Printf("Server: start");
       
   146 	
       
   147 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   148 
       
   149 	CActiveScheduler* pR = new CActiveScheduler;
       
   150 	if (pR == NULL)
       
   151 		return KErrNoMemory;
       
   152 	CActiveScheduler::Install(pR);
       
   153 	
       
   154 	CMyServer* pS = new CMyServer;
       
   155 	if (pS == NULL)
       
   156 		return KErrNoMemory;
       
   157 	TInt r = pS->Start(KServerName);
       
   158 	if (r != KErrNone)
       
   159 		return r;
       
   160 	RThread::Rendezvous(KErrNone);
       
   161 	
       
   162 	TRAP(r, CActiveScheduler::Start());
       
   163 	if (r != KErrNone)
       
   164 		return r;
       
   165 	
       
   166 	delete pS;
       
   167 	delete pR;
       
   168 	delete cleanup;
       
   169 	
       
   170 	RDebug::Printf("Server: exit");
       
   171 	return KErrNone;
       
   172 	}
       
   173 
       
   174 TInt ClientProcess()
       
   175 	{
       
   176 	RDebug::Printf("Client: open session");
       
   177 	RSession session;
       
   178 	session.Open();
       
   179 	TRequestStatus status;
       
   180 	RDebug::Printf("Client: send request");
       
   181 	session.Test(status);
       
   182 	RDebug::Printf("Client: exit");
       
   183 	return KErrNone;
       
   184 	}
       
   185 
       
   186 void TestServerPanic()
       
   187 	{
       
   188 	TRequestStatus status;
       
   189 	
       
   190 	test_KErrNone(TheSemaphore.CreateLocal(0));
       
   191 	
       
   192 	RDebug::Printf("Main: start server");
       
   193 	RThread serverThread;
       
   194 	test_KErrNone(serverThread.Create(_L("server"), ServerThread, 4096, NULL, NULL));
       
   195 	serverThread.Rendezvous(status);
       
   196 	serverThread.Resume();
       
   197 	User::WaitForRequest(status);
       
   198 	test_KErrNone(status.Int());
       
   199 
       
   200 	RDebug::Printf("Main: start client");
       
   201 	RProcess clientProcess;
       
   202 	test_KErrNone(clientProcess.Create(KMyName, _L("client")));
       
   203 	clientProcess.Resume();
       
   204 	clientProcess.Logon(status);
       
   205 	User::WaitForRequest(status);
       
   206 	test_KErrNone(clientProcess.ExitReason());
       
   207 	test_Equal(EExitKill, clientProcess.ExitType());
       
   208 
       
   209 	RDebug::Printf("Main: kick server");
       
   210 	TheSemaphore.Signal();
       
   211 	
       
   212 	RDebug::Printf("Main: wait for server to exit");
       
   213 	serverThread.Logon(status);
       
   214 	User::WaitForRequest(status);
       
   215 	test_KErrNone(serverThread.ExitReason());
       
   216 	test_Equal(EExitKill, serverThread.ExitType());
       
   217 
       
   218 	User::After(1);
       
   219 	RDebug::Printf("Main: exit");
       
   220 	}
       
   221 
       
   222 
       
   223 GLDEF_C TInt E32Main()
       
   224 //
       
   225 // Main
       
   226 //
       
   227 	{	
       
   228 
       
   229 	if (User::CommandLineLength())
       
   230 		return ClientProcess();
       
   231 
       
   232 	test.Title();
       
   233 	__UHEAP_MARK;
       
   234 	
       
   235 	test.Start(_L("Test threads"));
       
   236 
       
   237 	test.Next(_L("Test a thread suspending itself"));
       
   238 	TestSelfSuspend(EOwnerProcess);
       
   239 	TestSelfSuspend(EOwnerThread);
       
   240 
       
   241 	test.Next(_L("Test a server panicking a thread in another process that's already exited"));
       
   242 	TestServerPanic();
       
   243 	
       
   244 	test.End();
       
   245 	__UHEAP_MARKEND;
       
   246 	return(KErrNone);
       
   247 	}