1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/misc/t_destruct_slave.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,289 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\misc\t_destruct_slave.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#define __E32TEST_EXTENSION__
1.22 +
1.23 +#include <e32std.h>
1.24 +#include <e32std_private.h>
1.25 +#include <e32test.h>
1.26 +#include <e32debug.h>
1.27 +#include <e32msgqueue.h>
1.28 +
1.29 +#include "t_destruct.h"
1.30 +
1.31 +_LIT(KDynamicDll, "t_destruct_dll2");
1.32 +
1.33 +class TTestObject
1.34 + {
1.35 +public:
1.36 + TTestType iTestType;
1.37 +public:
1.38 + TTestObject();
1.39 + ~TTestObject();
1.40 + };
1.41 +
1.42 +RTest test(_L("t_desruct_slave"));
1.43 +TThreadId MainThreadId;
1.44 +TTestObject GlobalObjectWithDestructor;
1.45 +
1.46 +void Panic(TInt aReason)
1.47 + {
1.48 + User::Panic(_L("t_destruct_slave"), aReason);
1.49 + }
1.50 +
1.51 +TInt ExitThread(TAny*)
1.52 + {
1.53 + return KErrNone;
1.54 + }
1.55 +
1.56 +TInt PanicThread(TAny*)
1.57 + {
1.58 + Panic(KErrNone);
1.59 + return KErrNone;
1.60 + }
1.61 +
1.62 +TInt LoopThread(TAny*)
1.63 + {
1.64 + // Open handle on dynamic DLL in this thread
1.65 + RLibrary library;
1.66 + test_KErrNone(library.Load(KDynamicDll));
1.67 + for (;;)
1.68 + ;
1.69 + }
1.70 +
1.71 +TInt ChildThread(TAny* aArg)
1.72 + {
1.73 + TInt testType = (TInt)aArg;
1.74 + RThread mainThread;
1.75 + TInt r = mainThread.Open(MainThreadId);
1.76 + if (r != KErrNone)
1.77 + return r;
1.78 + // Open handle on dynamic DLL in this thread
1.79 + RLibrary library;
1.80 + test_KErrNone(library.Load(KDynamicDll));
1.81 + RThread().Rendezvous(KErrNone);
1.82 + TRequestStatus status;
1.83 + mainThread.Logon(status);
1.84 + User::WaitForRequest(status);
1.85 + if (mainThread.ExitType() != EExitKill)
1.86 + return KErrGeneral;
1.87 + if (mainThread.ExitReason() != KErrNone)
1.88 + return mainThread.ExitReason();
1.89 + mainThread.Close();
1.90 + if (testType != ETestRecursive)
1.91 + {
1.92 + RMsgQueue<TMessage> messageQueue;
1.93 + r = messageQueue.OpenGlobal(KMessageQueueName);
1.94 + if (r != KErrNone)
1.95 + return r;
1.96 + r = messageQueue.Send(EMessagePreDestruct);
1.97 + if (r != KErrNone)
1.98 + return r;
1.99 + }
1.100 + return testType;
1.101 + }
1.102 +
1.103 +TInt PermanentThread(TAny* aArg)
1.104 + {
1.105 + TInt testType = (TInt)aArg;
1.106 + // Open handle on dynamic DLL in this thread
1.107 + RLibrary library;
1.108 + TInt r = library.Load(KDynamicDll);
1.109 + if (r != KErrNone)
1.110 + return r;
1.111 + RMsgQueue<TMessage> messageQueue;
1.112 + r = messageQueue.OpenGlobal(KMessageQueueName);
1.113 + if (r != KErrNone)
1.114 + return r;
1.115 + r = messageQueue.Send(EMessagePreDestruct);
1.116 + if (r != KErrNone)
1.117 + return r;
1.118 + messageQueue.Close();
1.119 + User::SetCritical(User::EProcessPermanent);
1.120 + User::Exit(testType);
1.121 + return KErrGeneral;
1.122 + }
1.123 +
1.124 +TTestObject::TTestObject()
1.125 + {
1.126 + RDebug::Printf("t_destruct_slave constructor called\n");
1.127 + RMsgQueue<TMessage> messageQueue;
1.128 + TInt r = messageQueue.OpenGlobal(KMessageQueueName);
1.129 + if (r != KErrNone)
1.130 + Panic(r);
1.131 + messageQueue.Send(EMessageConstruct);
1.132 + if (r != KErrNone)
1.133 + Panic(r);
1.134 + }
1.135 +
1.136 +TTestObject::~TTestObject()
1.137 + {
1.138 + RDebug::Printf("t_destruct_slave destructor called\n");
1.139 + if (iTestType == ETestRecursive)
1.140 + {
1.141 + // Start child thread passing this thread's id
1.142 + MainThreadId = RThread().Id();
1.143 + RThread childThread;
1.144 + test_KErrNone(childThread.Create(_L("ChildThread"), ChildThread, 4096, NULL, (TAny*)iTestType));
1.145 + TRequestStatus status;
1.146 + childThread.Rendezvous(status);
1.147 + childThread.Resume();
1.148 +
1.149 + // Wait for child to open handle on this thread
1.150 + User::WaitForRequest(status);
1.151 + test_KErrNone(status.Int());
1.152 + childThread.Close();
1.153 +
1.154 + // Set this thread non-critical
1.155 + User::SetCritical(User::ENotCritical);
1.156 + }
1.157 + else if (iTestType == ETestDestructorExits)
1.158 + {
1.159 + User::Exit(iTestType);
1.160 + }
1.161 +
1.162 + RMsgQueue<TMessage> messageQueue;
1.163 + TInt r = messageQueue.OpenGlobal(KMessageQueueName);
1.164 + if (r != KErrNone)
1.165 + Panic(r);
1.166 + messageQueue.Send(EMessageDestruct);
1.167 + if (r != KErrNone)
1.168 + Panic(r);
1.169 + }
1.170 +
1.171 +TInt E32Main()
1.172 + {
1.173 + StaticMain();
1.174 +
1.175 + RBuf cmd;
1.176 + test_KErrNone(cmd.Create(User::CommandLineLength()));
1.177 + User::CommandLine(cmd);
1.178 +
1.179 + TLex lex(cmd);
1.180 + TTestType type;
1.181 + test_KErrNone(lex.Val((TInt&)type));
1.182 + GlobalObjectWithDestructor.iTestType = type;
1.183 +
1.184 + RMsgQueue<TMessage> messageQueue;
1.185 + test_KErrNone(messageQueue.OpenGlobal(KMessageQueueName));
1.186 +
1.187 + // Dynamically load DLL with global data
1.188 + RLibrary library;
1.189 + test_KErrNone(library.Load(KDynamicDll));
1.190 +
1.191 + switch(type)
1.192 + {
1.193 + case ETestMainThreadReturn:
1.194 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.195 + return type;
1.196 +
1.197 + case ETestMainThreadExit:
1.198 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.199 + User::Exit(type);
1.200 + break;
1.201 +
1.202 + case ETestChildThreadReturn:
1.203 + {
1.204 + // Start child thread passing this thread's id
1.205 + MainThreadId = RThread().Id();
1.206 + RThread childThread;
1.207 + test_KErrNone(childThread.Create(_L("ChildThread"), ChildThread, 4096, NULL, (TAny*)type));
1.208 + TRequestStatus status;
1.209 + childThread.Rendezvous(status);
1.210 + childThread.Resume();
1.211 +
1.212 + User::After(1);
1.213 +
1.214 + // Wait for child to open handle on this thread
1.215 + User::WaitForRequest(status);
1.216 + test_KErrNone(status.Int());
1.217 + childThread.Close();
1.218 +
1.219 + // Set this thread non-critical and exit
1.220 + User::SetCritical(User::ENotCritical);
1.221 + }
1.222 + break;
1.223 +
1.224 + case ETestOtherThreadExit:
1.225 + {
1.226 + RThread childThread;
1.227 + test_KErrNone(childThread.Create(_L("ChildThread"), ExitThread, 4096, NULL, (TAny*)type));
1.228 + childThread.Resume();
1.229 + TRequestStatus status;
1.230 + childThread.Logon(status);
1.231 + User::WaitForRequest(status);
1.232 + test_KErrNone(status.Int());
1.233 + childThread.Close();
1.234 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.235 + }
1.236 + return type;
1.237 +
1.238 + case ETestOtherThreadPanic:
1.239 + {
1.240 + RThread childThread;
1.241 + test_KErrNone(childThread.Create(_L("ChildThread"), PanicThread, 4096, NULL, (TAny*)type));
1.242 + childThread.Resume();
1.243 + TRequestStatus status;
1.244 + childThread.Logon(status);
1.245 + User::WaitForRequest(status);
1.246 + test_KErrNone(status.Int());
1.247 + childThread.Close();
1.248 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.249 + }
1.250 + return type;
1.251 +
1.252 + case ETestOtherThreadRunning:
1.253 + {
1.254 + RThread childThread;
1.255 + test_KErrNone(childThread.Create(_L("ChildThread"), LoopThread, 4096, NULL, (TAny*)type));
1.256 + childThread.Resume();
1.257 + childThread.Close();
1.258 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.259 + }
1.260 + return type;
1.261 +
1.262 + case ETestPermanentThreadExit:
1.263 + {
1.264 + RThread childThread;
1.265 + test_KErrNone(childThread.Create(_L("ChildThread"), PermanentThread, 4096, NULL, (TAny*)type));
1.266 + childThread.Resume();
1.267 + TRequestStatus status;
1.268 + childThread.Logon(status);
1.269 + User::WaitForRequest(status);
1.270 + test_KErrNone(status.Int());
1.271 + childThread.Close();
1.272 + }
1.273 + break;
1.274 +
1.275 + case ETestRecursive:
1.276 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.277 + break;
1.278 +
1.279 + case ETestDestructorExits:
1.280 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.281 + break;
1.282 +
1.283 + case ETestLastThreadPanic:
1.284 + test_KErrNone(messageQueue.Send(EMessagePreDestruct));
1.285 + Panic(type);
1.286 + break;
1.287 +
1.288 + default:
1.289 + test(EFalse);
1.290 + }
1.291 + return KErrNone;
1.292 + }