|         |      1 // Copyright (c) 2001-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\secure\t_rendezvous.cpp | 
|         |     15 // Overview: | 
|         |     16 // Test RThread and RProcess rendezvous | 
|         |     17 // API Information: | 
|         |     18 // RThread, RProcess | 
|         |     19 // Details: | 
|         |     20 // - Create a thread, request rendezvous, cancel rendezvous, request rendezvous | 
|         |     21 // again, resume thread and wait for rendezvous, verify results as expected. | 
|         |     22 // - Create a thread, request rendezvous, allow thread to die, verify results. | 
|         |     23 // - Create a thread, request rendezvous, allow thread to finish, verify results. | 
|         |     24 // - Create a process, request rendezvous, cancel rendezvous, request rendezvous | 
|         |     25 // again, resume process and wait for rendezvous, verify results as expected. | 
|         |     26 // - Create a process, request rendezvous, allow process to die, verify results. | 
|         |     27 // - Create a process, request rendezvous, allow process to finish, verify results. | 
|         |     28 // Platforms/Drives/Compatibility: | 
|         |     29 // All. | 
|         |     30 // Assumptions/Requirement/Pre-requisites: | 
|         |     31 // Failures and causes: | 
|         |     32 // Base Port information: | 
|         |     33 //  | 
|         |     34 // | 
|         |     35  | 
|         |     36 #include <e32test.h> | 
|         |     37  | 
|         |     38 LOCAL_D RTest test(_L("T_RENDEZVOUS")); | 
|         |     39  | 
|         |     40 _LIT(KSyncMutext,"T_RENDEZVOUS-sync-mutex"); | 
|         |     41 RMutex SyncMutex; | 
|         |     42  | 
|         |     43 void Wait() | 
|         |     44 	{ | 
|         |     45 	RMutex syncMutex; | 
|         |     46 	if(syncMutex.OpenGlobal(KSyncMutext)!=KErrNone) | 
|         |     47 		User::Invariant(); | 
|         |     48 	syncMutex.Wait(); | 
|         |     49 	syncMutex.Signal(); | 
|         |     50 	syncMutex.Close(); | 
|         |     51 	} | 
|         |     52  | 
|         |     53 const TInt KRendezvousOk = 1; | 
|         |     54  | 
|         |     55 TInt ThreadRendezvous(TAny *) | 
|         |     56 	{ | 
|         |     57 	RThread::Rendezvous(KRendezvousOk); | 
|         |     58 	Wait(); | 
|         |     59 	return KErrNone; | 
|         |     60 	} | 
|         |     61  | 
|         |     62 TInt ThreadDie(TAny *) | 
|         |     63 	{ | 
|         |     64 	User::Panic(_L("ThreadDie"),KErrDied); | 
|         |     65 	return KErrNone; | 
|         |     66 	} | 
|         |     67  | 
|         |     68 TInt ThreadFinish(TAny *) | 
|         |     69 	{ | 
|         |     70 	return KErrNone; | 
|         |     71 	} | 
|         |     72  | 
|         |     73 void TestThreadRendezvous() | 
|         |     74 	{ | 
|         |     75 	TRequestStatus rendezvousStatus; | 
|         |     76 	TRequestStatus rendezvousStatusCancel; | 
|         |     77 	TRequestStatus logonStatus; | 
|         |     78 	TInt r; | 
|         |     79 	RThread thread; | 
|         |     80  | 
|         |     81 	// | 
|         |     82  | 
|         |     83 	test.Start(_L("Create thread 'ThreadRendezvous'")); | 
|         |     84 	r=thread.Create(_L("ThreadRendezvous"),ThreadRendezvous,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL); | 
|         |     85 	test(r==KErrNone); | 
|         |     86  | 
|         |     87 	test.Next(_L("Request rendezvous")); | 
|         |     88 	thread.Rendezvous(rendezvousStatusCancel); | 
|         |     89 	test(rendezvousStatusCancel==KRequestPending); | 
|         |     90  | 
|         |     91 	test.Next(_L("Cancel rendezvous request")); | 
|         |     92 	r = thread.RendezvousCancel(rendezvousStatusCancel); | 
|         |     93 	test(r==KErrNone); | 
|         |     94 	test(rendezvousStatusCancel==KErrNone); | 
|         |     95  | 
|         |     96 	test.Next(_L("Request rendezvous again")); | 
|         |     97 	thread.Rendezvous(rendezvousStatus); | 
|         |     98 	test(rendezvousStatus==KRequestPending); | 
|         |     99  | 
|         |    100 	test.Next(_L("Also logon to thread")); | 
|         |    101 	thread.Logon(logonStatus); | 
|         |    102 	test(logonStatus==KRequestPending); | 
|         |    103  | 
|         |    104 	test.Next(_L("Resume thread and wait for rendezvous...")); | 
|         |    105 	SyncMutex.Wait(); | 
|         |    106 	thread.Resume(); | 
|         |    107 	User::WaitForRequest(rendezvousStatus,logonStatus); | 
|         |    108 	test(rendezvousStatus==KRendezvousOk); | 
|         |    109 	test(logonStatus==KRequestPending); | 
|         |    110 	test(rendezvousStatusCancel==KErrNone); | 
|         |    111  | 
|         |    112 	test.Next(_L("Rendezvous OK, now wait for thread to end...")); | 
|         |    113 	SyncMutex.Signal(); | 
|         |    114 	User::WaitForRequest(logonStatus); | 
|         |    115 	test(logonStatus==KErrNone); | 
|         |    116 	test(rendezvousStatusCancel==KErrNone); | 
|         |    117  | 
|         |    118 	CLOSE_AND_WAIT(thread); | 
|         |    119  | 
|         |    120 	// | 
|         |    121  | 
|         |    122 	test.Next(_L("Create thread 'ThreadDie'")); | 
|         |    123 	r=thread.Create(_L("ThreadDie"),ThreadDie,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL); | 
|         |    124 	test(r==KErrNone); | 
|         |    125  | 
|         |    126 	test.Next(_L("Request rendezvous")); | 
|         |    127 	thread.Rendezvous(rendezvousStatus); | 
|         |    128 	test(rendezvousStatus==KRequestPending); | 
|         |    129  | 
|         |    130 	test.Next(_L("Resume thread and wait for thread to die...")); | 
|         |    131 	TBool jit = User::JustInTime(); | 
|         |    132 	User::SetJustInTime(EFalse); | 
|         |    133 	thread.Resume(); | 
|         |    134 	User::WaitForRequest(rendezvousStatus); | 
|         |    135 	User::SetJustInTime(jit); | 
|         |    136 	test(rendezvousStatus==KErrDied); | 
|         |    137 	test(thread.ExitReason()==KErrDied); | 
|         |    138 	test(thread.ExitType()==EExitPanic); | 
|         |    139  | 
|         |    140 	CLOSE_AND_WAIT(thread); | 
|         |    141  | 
|         |    142 	// | 
|         |    143  | 
|         |    144 	test.Next(_L("Create thread 'ThreadFinish'")); | 
|         |    145 	r=thread.Create(_L("ThreadFinish"),ThreadFinish,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL); | 
|         |    146 	test(r==KErrNone); | 
|         |    147  | 
|         |    148 	test.Next(_L("Request rendezvous")); | 
|         |    149 	thread.Rendezvous(rendezvousStatus); | 
|         |    150 	test(rendezvousStatus==KRequestPending); | 
|         |    151  | 
|         |    152 	test.Next(_L("Resume thread and wait for thread to finish...")); | 
|         |    153 	thread.Resume(); | 
|         |    154 	User::WaitForRequest(rendezvousStatus); | 
|         |    155 	test(rendezvousStatus==KErrNone); | 
|         |    156 	test(thread.ExitReason()==KErrNone); | 
|         |    157 	test(thread.ExitType()==EExitKill); | 
|         |    158  | 
|         |    159 	CLOSE_AND_WAIT(thread); | 
|         |    160  | 
|         |    161 	// | 
|         |    162  | 
|         |    163 	test.End(); | 
|         |    164 	} | 
|         |    165  | 
|         |    166  | 
|         |    167 enum TTestProcessFunctions | 
|         |    168 	{ | 
|         |    169 	ETestProcessRendezvous, | 
|         |    170 	ETestProcessDie, | 
|         |    171 	ETestProcessFinish, | 
|         |    172 	}; | 
|         |    173  | 
|         |    174 #include "testprocess.h" | 
|         |    175  | 
|         |    176 TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2) | 
|         |    177 	{ | 
|         |    178 	(void)aArg1; // Keep compiler quiet about unused parameters | 
|         |    179 	(void)aArg2; | 
|         |    180  | 
|         |    181 	switch(aTestNum) | 
|         |    182 		{ | 
|         |    183 	case ETestProcessRendezvous: | 
|         |    184 		RProcess::Rendezvous(KRendezvousOk); | 
|         |    185 		Wait(); | 
|         |    186 		return KErrNone; | 
|         |    187  | 
|         |    188 	case ETestProcessDie: | 
|         |    189 		User::Panic(_L("ProcessDie"),KErrDied); | 
|         |    190 		return KErrNone; | 
|         |    191  | 
|         |    192 	case ETestProcessFinish: | 
|         |    193 		return KErrNone; | 
|         |    194  | 
|         |    195 	default: | 
|         |    196 		User::Panic(_L("T_RENDEZVOUS"),1); | 
|         |    197 		} | 
|         |    198 	return KErrNone; | 
|         |    199 	} | 
|         |    200  | 
|         |    201 void TestProcessRendezvous() | 
|         |    202 	{ | 
|         |    203 	TRequestStatus rendezvousStatus; | 
|         |    204 	TRequestStatus rendezvousStatusCancel; | 
|         |    205 	TRequestStatus logonStatus; | 
|         |    206 	TInt r; | 
|         |    207 	RTestProcess process; | 
|         |    208  | 
|         |    209 	test.Start(_L("Create new process")); | 
|         |    210 	process.Create(ETestProcessRendezvous); | 
|         |    211  | 
|         |    212 	test.Next(_L("Request rendezvous")); | 
|         |    213 	process.Rendezvous(rendezvousStatusCancel); | 
|         |    214 	test(rendezvousStatusCancel==KRequestPending); | 
|         |    215  | 
|         |    216 	test.Next(_L("Cancel rendezvous request")); | 
|         |    217 	r = process.RendezvousCancel(rendezvousStatusCancel); | 
|         |    218 	test(r==KErrNone); | 
|         |    219 	test(rendezvousStatusCancel==KErrNone); | 
|         |    220  | 
|         |    221 	test.Next(_L("Request rendezvous again")); | 
|         |    222 	process.Rendezvous(rendezvousStatus); | 
|         |    223 	test(rendezvousStatus==KRequestPending); | 
|         |    224  | 
|         |    225 	test.Next(_L("Also logon to process")); | 
|         |    226 	process.Logon(logonStatus); | 
|         |    227 	test(logonStatus==KRequestPending); | 
|         |    228  | 
|         |    229 	test.Next(_L("Resume process and wait for rendezvous...")); | 
|         |    230 	SyncMutex.Wait(); | 
|         |    231 	process.Resume(); | 
|         |    232 	User::WaitForRequest(rendezvousStatus,logonStatus); | 
|         |    233 	test(rendezvousStatus==KRendezvousOk); | 
|         |    234 	test(logonStatus==KRequestPending); | 
|         |    235 	test(rendezvousStatusCancel==KErrNone); | 
|         |    236  | 
|         |    237 	test.Next(_L("Rendezvous OK, now wait for process to end...")); | 
|         |    238 	SyncMutex.Signal(); | 
|         |    239 	User::WaitForRequest(logonStatus); | 
|         |    240 	test(logonStatus==KErrNone); | 
|         |    241 	test(rendezvousStatusCancel==KErrNone); | 
|         |    242  | 
|         |    243 	CLOSE_AND_WAIT(process); | 
|         |    244  | 
|         |    245 	// | 
|         |    246  | 
|         |    247 	test.Next(_L("Create new process")); | 
|         |    248 	process.Create(ETestProcessDie); | 
|         |    249  | 
|         |    250 	test.Next(_L("Request rendezvous")); | 
|         |    251 	process.Rendezvous(rendezvousStatus); | 
|         |    252 	test(rendezvousStatus==KRequestPending); | 
|         |    253  | 
|         |    254 	test.Next(_L("Resume process and wait for process to die...")); | 
|         |    255 	process.Resume(); | 
|         |    256 	User::WaitForRequest(rendezvousStatus); | 
|         |    257 	test(rendezvousStatus==KErrDied); | 
|         |    258 	test(process.ExitReason()==KErrDied); | 
|         |    259 	test(process.ExitType()==EExitPanic); | 
|         |    260  | 
|         |    261 	CLOSE_AND_WAIT(process); | 
|         |    262  | 
|         |    263 	// | 
|         |    264  | 
|         |    265 	test.Next(_L("Create new process")); | 
|         |    266 	process.Create(ETestProcessFinish); | 
|         |    267  | 
|         |    268 	test.Next(_L("Request rendezvous")); | 
|         |    269 	process.Rendezvous(rendezvousStatus); | 
|         |    270 	test(rendezvousStatus==KRequestPending); | 
|         |    271  | 
|         |    272 	test.Next(_L("Resume process and wait for process to finish...")); | 
|         |    273 	process.Resume(); | 
|         |    274 	User::WaitForRequest(rendezvousStatus); | 
|         |    275 	test(rendezvousStatus==KErrNone); | 
|         |    276 	test(process.ExitReason()==KErrNone); | 
|         |    277 	test(process.ExitType()==EExitKill); | 
|         |    278  | 
|         |    279 	CLOSE_AND_WAIT(process); | 
|         |    280  | 
|         |    281 	//  | 
|         |    282  | 
|         |    283 	test.End(); | 
|         |    284 	} | 
|         |    285  | 
|         |    286  | 
|         |    287  | 
|         |    288 GLDEF_C TInt E32Main() | 
|         |    289     { | 
|         |    290 	TBuf16<512> cmd; | 
|         |    291 	User::CommandLine(cmd); | 
|         |    292 	if(cmd.Length() && TChar(cmd[0]).IsDigit()) | 
|         |    293 		{ | 
|         |    294 		TInt function = -1; | 
|         |    295 		TInt arg1 = -1; | 
|         |    296 		TInt arg2 = -1; | 
|         |    297 		TLex lex(cmd); | 
|         |    298 		lex.Val(function); | 
|         |    299 		lex.SkipSpace(); | 
|         |    300 		lex.Val(arg1); | 
|         |    301 		lex.SkipSpace(); | 
|         |    302 		lex.Val(arg2); | 
|         |    303 		return DoTestProcess(function,arg1,arg2); | 
|         |    304 		} | 
|         |    305  | 
|         |    306 	test.Title(); | 
|         |    307 	test(SyncMutex.CreateGlobal(KSyncMutext)==KErrNone); | 
|         |    308  | 
|         |    309 	test.Start(_L("Test Thread rendezvous")); | 
|         |    310 	TestThreadRendezvous(); | 
|         |    311  | 
|         |    312 	test.Next(_L("Test Process rendezvous")); | 
|         |    313 	TestProcessRendezvous(); | 
|         |    314  | 
|         |    315 	SyncMutex.Close(); | 
|         |    316 	test.End(); | 
|         |    317  | 
|         |    318 	return(0); | 
|         |    319     } | 
|         |    320  |