os/kernelhwsrv/kerneltest/e32test/misc/t_destruct_slave.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-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\misc\t_destruct_slave.cpp
    15 // 
    16 //
    17 
    18 #define __E32TEST_EXTENSION__
    19 
    20 #include <e32std.h>
    21 #include <e32std_private.h>
    22 #include <e32test.h>
    23 #include <e32debug.h>
    24 #include <e32msgqueue.h>
    25 
    26 #include "t_destruct.h"
    27 
    28 _LIT(KDynamicDll, "t_destruct_dll2");
    29 
    30 class TTestObject
    31 	{
    32 public:
    33 	TTestType iTestType;
    34 public:
    35 	TTestObject();
    36 	~TTestObject();
    37 	};
    38 
    39 RTest test(_L("t_desruct_slave"));
    40 TThreadId MainThreadId;
    41 TTestObject GlobalObjectWithDestructor;
    42 
    43 void Panic(TInt aReason)
    44 	{
    45 	User::Panic(_L("t_destruct_slave"), aReason);
    46 	}
    47 
    48 TInt ExitThread(TAny*)
    49 	{
    50 	return KErrNone;
    51 	}
    52 
    53 TInt PanicThread(TAny*)
    54 	{
    55 	Panic(KErrNone);
    56 	return KErrNone;
    57 	}
    58 
    59 TInt LoopThread(TAny*)
    60 	{
    61 	// Open handle on dynamic DLL in this thread
    62 	RLibrary library;
    63 	test_KErrNone(library.Load(KDynamicDll));
    64 	for (;;)
    65 		;
    66 	}
    67 
    68 TInt ChildThread(TAny* aArg)
    69 	{
    70 	TInt testType = (TInt)aArg;
    71 	RThread mainThread;
    72 	TInt r = mainThread.Open(MainThreadId);
    73 	if (r != KErrNone)
    74 		return r;
    75 	// Open handle on dynamic DLL in this thread
    76 	RLibrary library;
    77 	test_KErrNone(library.Load(KDynamicDll));
    78 	RThread().Rendezvous(KErrNone);
    79 	TRequestStatus status;
    80 	mainThread.Logon(status);
    81 	User::WaitForRequest(status);
    82 	if (mainThread.ExitType() != EExitKill)
    83 		return KErrGeneral;
    84 	if (mainThread.ExitReason() != KErrNone)
    85 		return mainThread.ExitReason();
    86 	mainThread.Close();
    87 	if (testType != ETestRecursive)
    88 		{
    89 		RMsgQueue<TMessage> messageQueue;
    90 		r = messageQueue.OpenGlobal(KMessageQueueName);
    91 		if (r != KErrNone)
    92 			return r;
    93 		r = messageQueue.Send(EMessagePreDestruct);
    94 		if (r != KErrNone)
    95 			return r;
    96 		}
    97 	return testType;
    98 	}
    99 
   100 TInt PermanentThread(TAny* aArg)
   101 	{
   102 	TInt testType = (TInt)aArg;
   103 	// Open handle on dynamic DLL in this thread
   104 	RLibrary library;
   105 	TInt r = library.Load(KDynamicDll);
   106 	if (r != KErrNone)
   107 		return r;
   108 	RMsgQueue<TMessage> messageQueue;
   109 	r = messageQueue.OpenGlobal(KMessageQueueName);
   110 	if (r != KErrNone)
   111 		return r;
   112 	r = messageQueue.Send(EMessagePreDestruct);
   113 	if (r != KErrNone)
   114 		return r;
   115 	messageQueue.Close();
   116 	User::SetCritical(User::EProcessPermanent);
   117 	User::Exit(testType);
   118 	return KErrGeneral;
   119 	}
   120 
   121 TTestObject::TTestObject()
   122 	{
   123 	RDebug::Printf("t_destruct_slave constructor called\n");
   124 	RMsgQueue<TMessage> messageQueue;
   125 	TInt r = messageQueue.OpenGlobal(KMessageQueueName);
   126 	if (r != KErrNone)
   127 		Panic(r);
   128 	messageQueue.Send(EMessageConstruct);
   129 	if (r != KErrNone)
   130 		Panic(r);
   131 	}
   132 
   133 TTestObject::~TTestObject()
   134 	{
   135 	RDebug::Printf("t_destruct_slave destructor called\n");
   136 	if (iTestType == ETestRecursive)
   137 		{
   138 		// Start child thread passing this thread's id
   139 		MainThreadId = RThread().Id();
   140 		RThread childThread;
   141 		test_KErrNone(childThread.Create(_L("ChildThread"), ChildThread, 4096, NULL, (TAny*)iTestType));
   142 		TRequestStatus status;
   143 		childThread.Rendezvous(status);
   144 		childThread.Resume();
   145 
   146 		// Wait for child to open handle on this thread
   147 		User::WaitForRequest(status);
   148 		test_KErrNone(status.Int());
   149 		childThread.Close();
   150 
   151 		// Set this thread non-critical
   152 		User::SetCritical(User::ENotCritical);
   153 		}
   154 	else if (iTestType == ETestDestructorExits)
   155 		{
   156 		User::Exit(iTestType);
   157 		}
   158 
   159 	RMsgQueue<TMessage> messageQueue;
   160 	TInt r = messageQueue.OpenGlobal(KMessageQueueName);
   161 	if (r != KErrNone)
   162 		Panic(r);
   163 	messageQueue.Send(EMessageDestruct);
   164 	if (r != KErrNone)
   165 		Panic(r);
   166 	}
   167 
   168 TInt E32Main()
   169 	{
   170 	StaticMain();
   171 	
   172 	RBuf cmd;
   173 	test_KErrNone(cmd.Create(User::CommandLineLength()));
   174 	User::CommandLine(cmd);
   175 
   176 	TLex lex(cmd);
   177 	TTestType type;
   178 	test_KErrNone(lex.Val((TInt&)type));
   179 	GlobalObjectWithDestructor.iTestType = type;
   180 
   181 	RMsgQueue<TMessage> messageQueue;
   182 	test_KErrNone(messageQueue.OpenGlobal(KMessageQueueName));
   183 
   184 	// Dynamically load DLL with global data
   185 	RLibrary library;
   186 	test_KErrNone(library.Load(KDynamicDll));
   187 	
   188 	switch(type)
   189 		{
   190 		case ETestMainThreadReturn:
   191 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   192 			return type;
   193 
   194 		case ETestMainThreadExit:
   195 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   196 			User::Exit(type);
   197 			break;
   198 
   199 		case ETestChildThreadReturn:
   200 			{
   201 			// Start child thread passing this thread's id
   202 			MainThreadId = RThread().Id();
   203 			RThread childThread;
   204 			test_KErrNone(childThread.Create(_L("ChildThread"), ChildThread, 4096, NULL, (TAny*)type));
   205 			TRequestStatus status;
   206 			childThread.Rendezvous(status);
   207 			childThread.Resume();
   208 
   209 			User::After(1);
   210 
   211 			// Wait for child to open handle on this thread
   212 			User::WaitForRequest(status);
   213 			test_KErrNone(status.Int());
   214 			childThread.Close();
   215 
   216 			// Set this thread non-critical and exit
   217 			User::SetCritical(User::ENotCritical);
   218 			}
   219 			break;
   220 
   221 		case ETestOtherThreadExit:
   222 			{
   223 			RThread childThread;
   224 			test_KErrNone(childThread.Create(_L("ChildThread"), ExitThread, 4096, NULL, (TAny*)type));
   225 			childThread.Resume();
   226 			TRequestStatus status;
   227 			childThread.Logon(status);
   228 			User::WaitForRequest(status);
   229 			test_KErrNone(status.Int());
   230 			childThread.Close();
   231 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   232 			}
   233 			return type;
   234 
   235 		case ETestOtherThreadPanic:
   236 			{
   237 			RThread childThread;
   238 			test_KErrNone(childThread.Create(_L("ChildThread"), PanicThread, 4096, NULL, (TAny*)type));
   239 			childThread.Resume();
   240 			TRequestStatus status;
   241 			childThread.Logon(status);
   242 			User::WaitForRequest(status);
   243 			test_KErrNone(status.Int());
   244 			childThread.Close();
   245 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   246 			}
   247 			return type;
   248 			
   249 		case ETestOtherThreadRunning:
   250 			{
   251 			RThread childThread;
   252 			test_KErrNone(childThread.Create(_L("ChildThread"), LoopThread, 4096, NULL, (TAny*)type));
   253 			childThread.Resume();
   254 			childThread.Close();
   255 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   256 			}
   257 			return type;
   258 			
   259 		case ETestPermanentThreadExit:
   260 			{
   261 			RThread childThread;
   262 			test_KErrNone(childThread.Create(_L("ChildThread"), PermanentThread, 4096, NULL, (TAny*)type));
   263 			childThread.Resume();
   264 			TRequestStatus status;
   265 			childThread.Logon(status);
   266 			User::WaitForRequest(status);
   267 			test_KErrNone(status.Int());
   268 			childThread.Close();
   269 			}
   270 			break;
   271 			
   272 		case ETestRecursive:
   273 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   274 			break;
   275 
   276 		case ETestDestructorExits:
   277 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   278 			break;
   279 
   280 		case ETestLastThreadPanic:
   281 			test_KErrNone(messageQueue.Send(EMessagePreDestruct));
   282 			Panic(type);
   283 			break;
   284 			
   285 		default:
   286 			test(EFalse);
   287 		}
   288 	return KErrNone;
   289 	}