|
1 // Copyright (c) 2008-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\demandpaging\t_svrpinning.cpp |
|
15 // Overview: |
|
16 // Test the pinning of RMessage descriptor arguments. |
|
17 // API Information: |
|
18 // RMessage2, RMessagePtr2, RSessionBase, CSession2, CServer2 |
|
19 // Details: |
|
20 // Platforms/Drives/Compatibility: |
|
21 // All. |
|
22 // Assumptions/Requirement/Pre-requisites: |
|
23 // Failures and causes: |
|
24 // Base Port information: |
|
25 // |
|
26 // |
|
27 |
|
28 #define __E32TEST_EXTENSION__ |
|
29 |
|
30 #include <e32std.h> |
|
31 #include <e32std_private.h> |
|
32 #include <e32def.h> |
|
33 #include <e32def_private.h> |
|
34 #include <e32test.h> |
|
35 #include <e32panic.h> |
|
36 #include <dptest.h> |
|
37 #include <u32hal.h> |
|
38 #include <hal.h> |
|
39 |
|
40 const TInt KHeapMinSize=0x1000; |
|
41 const TInt KHeapMaxSize=0x1000; |
|
42 |
|
43 const TUint KPageSize = 0x1000; |
|
44 TInt gPageSize; |
|
45 TUint gPageMask; |
|
46 TBool gDataPagingSupport = EFalse; |
|
47 TBool gProcessPaged; |
|
48 enum TServerPinning |
|
49 { |
|
50 EServerDefault, |
|
51 EServerPinning, |
|
52 EServerNotPinning, |
|
53 EServerSetPinningTooLate, |
|
54 EServerPinningCount, |
|
55 }; |
|
56 TInt gServerPinningState; |
|
57 |
|
58 class CTestServer : public CServer2 |
|
59 { |
|
60 public: |
|
61 CTestServer(TInt aPriority); |
|
62 protected: |
|
63 //override the pure virtual functions: |
|
64 virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const; |
|
65 }; |
|
66 |
|
67 |
|
68 class CTestSession : public CSession2 |
|
69 { |
|
70 public: |
|
71 enum TTestMode |
|
72 { |
|
73 EStop, |
|
74 ETestPinAll, |
|
75 ETestPinEven, |
|
76 ETestPinOdd, |
|
77 ETestPin3, |
|
78 ETestPin2, |
|
79 ETestPin1, |
|
80 ETestPin0, |
|
81 ETestPinWritable, |
|
82 ETestUnpinWritable, |
|
83 ETestPinOOM, |
|
84 ETestPinDefault, |
|
85 ETestDeadServer, |
|
86 }; |
|
87 //Override pure virtual |
|
88 IMPORT_C virtual void ServiceL(const RMessage2& aMessage); |
|
89 private: |
|
90 TInt CheckDesPresent(const RMessage2& aMessage, TUint aArgIndex, TBool aExpected, TBool aWrite); |
|
91 TInt CheckArgsPresent(const RMessage2& aMessage, TBool arg0Present, TBool arg1Present, TBool arg2Present, TBool arg3Present, TBool aWrite); |
|
92 TBool iClientDied; |
|
93 }; |
|
94 |
|
95 |
|
96 class CMyActiveScheduler : public CActiveScheduler |
|
97 { |
|
98 public: |
|
99 virtual void Error(TInt anError) const; //override pure virtual error function |
|
100 }; |
|
101 |
|
102 |
|
103 class RSession : public RSessionBase |
|
104 { |
|
105 public: |
|
106 TInt PublicSendReceive(TInt aFunction, const TIpcArgs &aPtr) |
|
107 { |
|
108 return (SendReceive(aFunction, aPtr)); |
|
109 } |
|
110 TInt PublicCreateSession(const TDesC& aServer,TInt aMessageSlots) |
|
111 { |
|
112 return (CreateSession(aServer,User::Version(),aMessageSlots)); |
|
113 } |
|
114 }; |
|
115 |
|
116 |
|
117 _LIT(KServerName,"CTestServer"); |
|
118 |
|
119 TBool UpdateExpected(TBool aExpected) |
|
120 { |
|
121 if (!gDataPagingSupport // Data paging is not supported so memory should always be present |
|
122 || gServerPinningState == EServerPinning // The server is a pinning server. |
|
123 /*|| (gServerPinningState == EServerDefault && !gProcessPaged)*/// The process isn't paged and default server policy |
|
124 ) |
|
125 { |
|
126 aExpected = ETrue; |
|
127 } |
|
128 return aExpected; |
|
129 } |
|
130 |
|
131 |
|
132 CTestServer::CTestServer(TInt aPriority) |
|
133 // |
|
134 // Constructor - sets name |
|
135 // |
|
136 : CServer2(aPriority) |
|
137 {} |
|
138 |
|
139 CSession2* CTestServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/) const |
|
140 // |
|
141 // Virtual fn - checks version supported and creates a CTestSession |
|
142 // |
|
143 { |
|
144 TVersion version(KE32MajorVersionNumber,KE32MinorVersionNumber,KE32BuildVersionNumber); |
|
145 if (User::QueryVersionSupported(version,aVersion)==EFalse) |
|
146 User::Leave(KErrNotSupported); |
|
147 CTestSession* newCTestSession = new CTestSession; |
|
148 if (newCTestSession==NULL) |
|
149 User::Panic(_L("NewSessionL failure"), KErrNoMemory); |
|
150 return(newCTestSession); |
|
151 } |
|
152 |
|
153 RSemaphore gSem; |
|
154 RSemaphore gSem1; |
|
155 |
|
156 TInt CTestSession::CheckDesPresent(const RMessage2& aMessage, TUint aArgIndex, TBool aExpected, TBool aWrite) |
|
157 { |
|
158 if (aExpected) |
|
159 RDebug::Printf(" Checking message argument at %d is present", aArgIndex); |
|
160 else |
|
161 RDebug::Printf(" Checking message argument at %d is not present", aArgIndex); |
|
162 |
|
163 // Get the length of the descriptor and verify it is as expected. |
|
164 TInt length = aMessage.GetDesLength(aArgIndex); |
|
165 if (length < KErrNone) |
|
166 { |
|
167 RDebug::Printf(" Error getting descriptor length %d", length); |
|
168 return length; |
|
169 } |
|
170 if (length < 3) |
|
171 {// The incorrect descriptor length. |
|
172 RDebug::Printf(" Error - Descriptor length too small %d", length); |
|
173 return KErrArgument; |
|
174 } |
|
175 if (!aWrite) |
|
176 {// Now read the descriptor and verify that it is present or not. |
|
177 TBuf8<5> des; |
|
178 TInt r = aMessage.Read(aArgIndex, des); |
|
179 TBool pass; |
|
180 if (iClientDied) |
|
181 pass = r == KErrDied || r == KErrBadDescriptor; |
|
182 else |
|
183 pass = r == (aExpected ? KErrNone : KErrBadDescriptor); |
|
184 if (!pass) |
|
185 { |
|
186 RDebug::Printf(" Error reading descriptor data r %d", r); |
|
187 return KErrGeneral; |
|
188 } |
|
189 if (r==KErrNone && (des[0] != 'a' || des[1] != 'r' || des[2] != 'g')) |
|
190 {// The incorrect descriptor data has been passed. |
|
191 RDebug::Printf(" Error in descriptor data is corrupt r %d", r); |
|
192 return KErrArgument; |
|
193 } |
|
194 } |
|
195 else |
|
196 {// Now write to the maximum length of the descriptor. |
|
197 TInt max = aMessage.GetDesMaxLength(aArgIndex); |
|
198 if (max < 0) |
|
199 { |
|
200 RDebug::Printf(" Error getting descriptor max. length %d", max); |
|
201 return length; |
|
202 } |
|
203 HBufC8* argTmp = HBufC8::New(max); |
|
204 TPtr8 argPtr = argTmp->Des(); |
|
205 argPtr.SetLength(max); |
|
206 for (TInt i = 0; i < max; i++) |
|
207 argPtr[i] = (TUint8)aArgIndex; |
|
208 TInt r = aMessage.Write(aArgIndex, argPtr); |
|
209 TBool pass; |
|
210 if (iClientDied) |
|
211 pass = r == KErrDied || r == KErrBadDescriptor; |
|
212 else |
|
213 pass = r == (aExpected ? KErrNone : KErrBadDescriptor); |
|
214 if (!pass) |
|
215 { |
|
216 RDebug::Printf(" Error writing to the descriptor data r %d", r); |
|
217 return KErrGeneral; |
|
218 } |
|
219 } |
|
220 |
|
221 if (!aExpected) |
|
222 {// The client should have been killed as the data wasn't present. |
|
223 if(!iClientDied) |
|
224 User::After(500000); // allow time for client to die before next test |
|
225 iClientDied = ETrue; |
|
226 } |
|
227 return KErrNone; |
|
228 } |
|
229 |
|
230 TInt CTestSession::CheckArgsPresent(const RMessage2& aMessage, TBool arg0Present, TBool arg1Present, TBool arg2Present, TBool arg3Present, TBool aWrite=EFalse) |
|
231 { |
|
232 // Adjust the pinning status expected based on the default policies. |
|
233 // (Must do this before anything else as UpdateExpected() accessed paged global data) |
|
234 arg0Present = UpdateExpected(arg0Present); |
|
235 arg1Present = UpdateExpected(arg1Present); |
|
236 arg2Present = UpdateExpected(arg2Present); |
|
237 arg3Present = UpdateExpected(arg3Present); |
|
238 |
|
239 // Flush the cache so on paged systems, unpinned paged memory will be discarded. |
|
240 DPTest::FlushCache(); |
|
241 |
|
242 TInt r = User::SetRealtimeState(User::ERealtimeStateOn); |
|
243 if (r != KErrNone) |
|
244 { |
|
245 RDebug::Printf("Error setting realtime state r = %d", r); |
|
246 return r; |
|
247 } |
|
248 |
|
249 r = CheckDesPresent(aMessage, 0, arg0Present, aWrite); |
|
250 if (r == KErrNone) |
|
251 r = CheckDesPresent(aMessage, 1, arg1Present, aWrite); |
|
252 if (r == KErrNone) |
|
253 r = CheckDesPresent(aMessage, 2, arg2Present, aWrite); |
|
254 if (r == KErrNone) |
|
255 r = CheckDesPresent(aMessage, 3, arg3Present, aWrite); |
|
256 |
|
257 User::SetRealtimeState(User::ERealtimeStateOff); |
|
258 |
|
259 return r; |
|
260 } |
|
261 |
|
262 void CTestSession::ServiceL(const RMessage2& aMessage) |
|
263 // |
|
264 // Virtual message-handler |
|
265 // |
|
266 { |
|
267 TInt r = KErrNone; |
|
268 iClientDied = EFalse; |
|
269 switch (aMessage.Function()) |
|
270 { |
|
271 case EStop: |
|
272 CActiveScheduler::Stop(); |
|
273 break; |
|
274 case ETestPinAll: |
|
275 r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, ETrue); |
|
276 break; |
|
277 case ETestPinOdd: |
|
278 r = CheckArgsPresent(aMessage, EFalse, ETrue, EFalse, ETrue); |
|
279 break; |
|
280 case ETestPinEven: |
|
281 r = CheckArgsPresent(aMessage, ETrue, EFalse, ETrue, EFalse); |
|
282 break; |
|
283 case ETestPin3: |
|
284 r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, EFalse); |
|
285 break; |
|
286 case ETestPin2: |
|
287 r = CheckArgsPresent(aMessage, ETrue, ETrue, EFalse, EFalse); |
|
288 break; |
|
289 case ETestPin1: |
|
290 r = CheckArgsPresent(aMessage, ETrue, EFalse, EFalse, EFalse); |
|
291 break; |
|
292 case ETestPin0: |
|
293 case ETestPinDefault: |
|
294 r = CheckArgsPresent(aMessage, EFalse, EFalse, EFalse, EFalse); |
|
295 break; |
|
296 case ETestPinWritable: |
|
297 r = CheckArgsPresent(aMessage, ETrue, ETrue, ETrue, ETrue, ETrue); |
|
298 break; |
|
299 case ETestUnpinWritable: |
|
300 r = CheckArgsPresent(aMessage, EFalse, EFalse, EFalse, EFalse, ETrue); |
|
301 break; |
|
302 default: |
|
303 r = KErrNotSupported; |
|
304 |
|
305 } |
|
306 aMessage.Complete(r); |
|
307 |
|
308 // If descriptors aren't as expected then panic so the test will fail. |
|
309 if (r != KErrNone) |
|
310 User::Panic(_L("ServiceL failure"), r); |
|
311 } |
|
312 |
|
313 // CTestSession funtions |
|
314 |
|
315 void CMyActiveScheduler::Error(TInt anError) const |
|
316 // |
|
317 // Virtual error handler |
|
318 // |
|
319 { |
|
320 User::Panic(_L("CMyActiveScheduer::Error"), anError); |
|
321 } |
|
322 |
|
323 TInt ServerThread(TAny* aPinningAttrib) |
|
324 // |
|
325 // Passed as the server thread in 2 tests - sets up and runs CTestServer |
|
326 // |
|
327 { |
|
328 RTest test(_L("T_SVRPINNING...server")); |
|
329 CMyActiveScheduler* pScheduler = new CMyActiveScheduler; |
|
330 if (pScheduler == NULL) |
|
331 { |
|
332 gSem.Signal(); |
|
333 test(0); |
|
334 } |
|
335 |
|
336 CActiveScheduler::Install(pScheduler); |
|
337 |
|
338 CTestServer* pServer = new CTestServer(0); |
|
339 if (pServer == NULL) |
|
340 { |
|
341 gSem.Signal(); |
|
342 test(0); |
|
343 } |
|
344 |
|
345 // Set the pinning attributes of the server. |
|
346 TServerPinning pinningAttrib = (TServerPinning)(TInt)aPinningAttrib; |
|
347 switch (pinningAttrib) |
|
348 { |
|
349 case EServerDefault : |
|
350 case EServerSetPinningTooLate : |
|
351 break; |
|
352 case EServerPinning : |
|
353 pServer->SetPinClientDescriptors(ETrue); |
|
354 break; |
|
355 case EServerNotPinning : |
|
356 pServer->SetPinClientDescriptors(EFalse); |
|
357 break; |
|
358 default : |
|
359 break; |
|
360 } |
|
361 |
|
362 //Starting a CServer2 also Adds it to the ActiveScheduler |
|
363 TInt r = pServer->Start(KServerName); |
|
364 if (r != KErrNone) |
|
365 { |
|
366 gSem.Signal(); |
|
367 test(0); |
|
368 } |
|
369 |
|
370 if (pinningAttrib == EServerSetPinningTooLate) |
|
371 { |
|
372 pServer->SetPinClientDescriptors(EFalse); |
|
373 } |
|
374 |
|
375 test.Next(_L("Start ActiveScheduler and signal to client")); |
|
376 test.Printf(_L(" There might be something going on beneath this window\n")); |
|
377 gSem.Signal(); |
|
378 CActiveScheduler::Start(); |
|
379 test.Next(_L("Destroy ActiveScheduler")); |
|
380 delete pScheduler; |
|
381 delete pServer; |
|
382 |
|
383 test.Close(); |
|
384 |
|
385 return (KErrNone); |
|
386 } |
|
387 |
|
388 |
|
389 |
|
390 #include <e32svr.h> |
|
391 |
|
392 void dummyFunction(TUint8* /*a0*/, TUint8* /*a1*/, TUint8* /*a2*/, TUint8* /*a3*/, TUint8* /*a4*/, TUint8* /*a5*/) |
|
393 { |
|
394 } |
|
395 |
|
396 TInt ClientThread(TAny* aTestMode) |
|
397 // |
|
398 // Passed as the first client thread - signals the server to do several tests |
|
399 // |
|
400 { |
|
401 // Create the message arguments to be pinned. Should be one of each type of |
|
402 // descriptor to test that the pinning code can correctly pin each type |
|
403 // descriptor data. Each descriptor's data should in a separate page in |
|
404 // thread's stack to ensure that access to each argument will cause a |
|
405 // separate page fault. |
|
406 |
|
407 TUint8 argBufs[KPageSize*(6+2)]; // enough for 6 whole pages |
|
408 TUint8* argBuf0 = (TUint8*)(TUintPtr(argBufs+gPageMask)&~gPageMask); |
|
409 TUint8* argBuf1 = argBuf0+KPageSize; |
|
410 TUint8* argBuf2 = argBuf1+KPageSize; |
|
411 TUint8* argBuf3 = argBuf2+KPageSize; |
|
412 TUint8* argBuf4 = argBuf3+KPageSize; |
|
413 TUint8* argBuf5 = argBuf4+KPageSize; |
|
414 |
|
415 argBuf0[0]='a'; argBuf0[1]='r'; argBuf0[2]='g'; argBuf0[3]='0'; argBuf0[4]='\0'; |
|
416 TPtr8 arg0(argBuf0, 5, 20); |
|
417 |
|
418 TBufC8<5>& arg1 = *(TBufC8<5>*)argBuf1; |
|
419 new (&arg1) TBufC8<5>((const TUint8*)"arg1"); |
|
420 |
|
421 argBuf2[0]='a'; argBuf2[1]='r'; argBuf2[2]='g'; argBuf2[3]='1'; argBuf2[4]='\0'; |
|
422 TPtrC8 arg2((const TUint8*)argBuf2); |
|
423 |
|
424 TBuf8<50>& arg3 = *(TBuf8<50>*)argBuf3; |
|
425 new (&arg3) TBuf8<50>((const TUint8*)"arg3"); |
|
426 |
|
427 // For some tests use this 5th and final type of descriptor. |
|
428 HBufC8* argTmp = HBufC8::New(7); |
|
429 *argTmp = (const TUint8*)"argTmp"; |
|
430 RBuf8 argTmpBuf(argTmp); |
|
431 |
|
432 // Need a couple of extra writable argments |
|
433 argBuf4[0]='a'; argBuf4[1]='r'; argBuf4[2]='g'; argBuf4[3]='4'; argBuf4[4]='\0'; |
|
434 TPtr8 arg4(argBuf4, 5, 20); |
|
435 argBuf5[0]='a'; argBuf5[1]='r'; argBuf5[2]='g'; argBuf5[3]='5'; argBuf5[4]='\0'; |
|
436 TPtr8 arg5(argBuf5, 5, 20); |
|
437 |
|
438 RTest test(_L("T_SVRPINNING...client")); |
|
439 RSession session; |
|
440 TInt r = session.PublicCreateSession(_L("CTestServer"),5); |
|
441 if (r != KErrNone) |
|
442 { |
|
443 gSem.Signal(); |
|
444 test(0); |
|
445 } |
|
446 |
|
447 switch((TInt)aTestMode) |
|
448 { |
|
449 case CTestSession::ETestPinAll: |
|
450 test.Printf(_L("Test pinning all args\n")); |
|
451 r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs()); |
|
452 break; |
|
453 |
|
454 case CTestSession::ETestPinOdd: |
|
455 test.Printf(_L("Test pinning odd args\n")); |
|
456 r = session.PublicSendReceive(CTestSession::ETestPinOdd, TIpcArgs(&arg0, &argTmpBuf, &arg2, &arg3).PinArgs(EFalse, ETrue, EFalse, ETrue)); |
|
457 break; |
|
458 |
|
459 case CTestSession::ETestPinEven: |
|
460 test.Printf(_L("Test pinning even args\n")); |
|
461 r = session.PublicSendReceive(CTestSession::ETestPinEven, TIpcArgs(&arg0, &arg1, argTmp, &arg3).PinArgs(ETrue, EFalse, ETrue, EFalse)); |
|
462 break; |
|
463 |
|
464 case CTestSession::ETestPin3: |
|
465 test.Printf(_L("Test pinning 3 args\n")); |
|
466 r = session.PublicSendReceive(CTestSession::ETestPin3, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs(ETrue, ETrue, ETrue, EFalse)); |
|
467 break; |
|
468 |
|
469 case CTestSession::ETestPin2: |
|
470 test.Printf(_L("Test pinning 2 args\n")); |
|
471 r = session.PublicSendReceive(CTestSession::ETestPin2, TIpcArgs(argTmp, &arg1, &arg2, &arg3).PinArgs(ETrue, ETrue, EFalse, EFalse)); |
|
472 break; |
|
473 |
|
474 case CTestSession::ETestPin1: |
|
475 test.Printf(_L("Test pinning 1 args\n")); |
|
476 r = session.PublicSendReceive(CTestSession::ETestPin1, TIpcArgs(&argTmpBuf, &arg1, &arg2, &arg3).PinArgs(ETrue, EFalse, EFalse, EFalse)); |
|
477 break; |
|
478 |
|
479 case CTestSession::ETestPin0: |
|
480 test.Printf(_L("Test pinning 0 args\n")); |
|
481 r = session.PublicSendReceive(CTestSession::ETestPin0, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs(EFalse, EFalse, EFalse, EFalse)); |
|
482 break; |
|
483 |
|
484 case CTestSession::ETestPinDefault: |
|
485 test.Printf(_L("Test the default pinning policy of this server\n")); |
|
486 r = session.PublicSendReceive(CTestSession::ETestPinDefault, TIpcArgs(&arg0, &arg1, &arg2, argTmp)); |
|
487 break; |
|
488 |
|
489 case CTestSession::ETestPinWritable: |
|
490 test.Printf(_L("Test writing to pinned descriptors\n")); |
|
491 r = session.PublicSendReceive(CTestSession::ETestPinWritable, TIpcArgs(&arg0, &arg3, &arg4, &arg5).PinArgs(ETrue, ETrue, ETrue, ETrue)); |
|
492 // Verify the index of each argument has been written to each descriptor. |
|
493 { |
|
494 TUint maxLength = arg0.MaxLength(); |
|
495 test_Equal(maxLength, arg0.Length()); |
|
496 TUint j = 0; |
|
497 for (; j < maxLength; j++) |
|
498 test_Equal(0, arg0[j]); |
|
499 maxLength = arg3.MaxLength(); |
|
500 test_Equal(maxLength, arg3.Length()); |
|
501 for (j = 0; j < maxLength; j++) |
|
502 test_Equal(1, arg3[j]); |
|
503 maxLength = arg4.MaxLength(); |
|
504 test_Equal(maxLength, arg4.Length()); |
|
505 for (j = 0; j < maxLength; j++) |
|
506 test_Equal(2, arg4[j]); |
|
507 maxLength = arg5.MaxLength(); |
|
508 test_Equal(maxLength, arg5.Length()); |
|
509 for (j = 0; j < maxLength; j++) |
|
510 test_Equal(3, arg5[j]); |
|
511 } |
|
512 break; |
|
513 |
|
514 case CTestSession::ETestUnpinWritable: |
|
515 test.Printf(_L("Test writing to unpinned descriptors\n")); |
|
516 r = session.PublicSendReceive(CTestSession::ETestUnpinWritable, TIpcArgs(&arg0, &arg3, &arg4, &arg5).PinArgs(EFalse, EFalse, EFalse, EFalse)); |
|
517 // Verify the index of each argument has been written to each descriptor. |
|
518 // Unless this is a pinnning server than the thread will be panicked before we reach there. |
|
519 { |
|
520 TUint maxLength = arg0.MaxLength(); |
|
521 test_Equal(maxLength, arg0.Length()); |
|
522 TUint j = 0; |
|
523 for (j = 0; j < maxLength; j++) |
|
524 test_Equal(0, arg0[j]); |
|
525 maxLength = arg3.MaxLength(); |
|
526 test_Equal(maxLength, arg3.Length()); |
|
527 for (j = 0; j < maxLength; j++) |
|
528 test_Equal(1, arg3[j]); |
|
529 maxLength = arg4.MaxLength(); |
|
530 test_Equal(maxLength, arg4.Length()); |
|
531 for (j = 0; j < maxLength; j++) |
|
532 test_Equal(2, arg4[j]); |
|
533 maxLength = arg5.MaxLength(); |
|
534 test_Equal(maxLength, arg5.Length()); |
|
535 for (j = 0; j < maxLength; j++) |
|
536 test_Equal(3, arg5[j]); |
|
537 } |
|
538 break; |
|
539 |
|
540 case CTestSession::ETestDeadServer: |
|
541 test.Printf(_L("Test pinning to dead server\n")); |
|
542 gSem.Signal(); |
|
543 gSem1.Wait(); |
|
544 r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs()); |
|
545 break; |
|
546 |
|
547 case CTestSession::ETestPinOOM: |
|
548 test.Printf(_L("Pinning OOM tests\n")); |
|
549 __KHEAP_MARK; |
|
550 const TUint KMaxKernelAllocations = 1024; |
|
551 TUint i; |
|
552 r = KErrNoMemory; |
|
553 for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++) |
|
554 { |
|
555 __KHEAP_FAILNEXT(i); |
|
556 r = session.PublicSendReceive(CTestSession::ETestPinAll, TIpcArgs(&arg0, &arg1, &arg2, &arg3).PinArgs()); |
|
557 __KHEAP_RESET; |
|
558 } |
|
559 test.Printf(_L("SendReceive took %d tries\n"),i); |
|
560 test_KErrNone(r); |
|
561 |
|
562 __KHEAP_MARKEND; |
|
563 break; |
|
564 } |
|
565 |
|
566 session.Close(); |
|
567 test.Close(); |
|
568 return r; |
|
569 } |
|
570 |
|
571 |
|
572 GLDEF_C TInt E32Main() |
|
573 { |
|
574 RTest test(_L("T_SVRPINNING...main")); |
|
575 test.Title(); |
|
576 |
|
577 |
|
578 if (DPTest::Attributes() & DPTest::ERomPaging) |
|
579 test.Printf(_L("Rom paging supported\n")); |
|
580 if (DPTest::Attributes() & DPTest::ECodePaging) |
|
581 test.Printf(_L("Code paging supported\n")); |
|
582 if (DPTest::Attributes() & DPTest::EDataPaging) |
|
583 { |
|
584 test.Printf(_L("Data paging supported\n")); |
|
585 gDataPagingSupport = ETrue; |
|
586 } |
|
587 |
|
588 // Determine the data paging attribute. |
|
589 RProcess process; // Default to point to current process. |
|
590 gProcessPaged = process.DefaultDataPaged(); |
|
591 test.Printf(_L("Process data paged %x\n"), gProcessPaged); |
|
592 |
|
593 test.Start(_L("Test IPC message arguments pinning")); |
|
594 test_KErrNone(HAL::Get(HAL::EMemoryPageSize, gPageSize)); |
|
595 gPageMask = gPageSize - 1; |
|
596 test_Equal(KPageSize, gPageSize); |
|
597 // Disable JIT as we are testing panics and don't want the emulator to hang. |
|
598 TBool justInTime = User::JustInTime(); |
|
599 User::SetJustInTime(EFalse); |
|
600 |
|
601 TBool exitFailure = EFalse; |
|
602 for ( gServerPinningState = EServerDefault; |
|
603 gServerPinningState < EServerSetPinningTooLate && !exitFailure; |
|
604 gServerPinningState++) |
|
605 { |
|
606 // Create the server with the specified pinning mode. |
|
607 switch (gServerPinningState) |
|
608 { |
|
609 case EServerDefault : |
|
610 test.Next(_L("Test server with default pinning policy")); |
|
611 break; |
|
612 case EServerPinning : |
|
613 test.Next(_L("Test server with pinning policy")); |
|
614 break; |
|
615 case EServerNotPinning : |
|
616 test.Next(_L("Test server with not pinning policy")); |
|
617 break; |
|
618 } |
|
619 test_KErrNone(gSem.CreateLocal(0)); |
|
620 test_KErrNone(gSem1.CreateLocal(0)); |
|
621 // Create the server thread it needs to have a unpaged stack and heap. |
|
622 TThreadCreateInfo serverInfo(_L("Server Thread"), ServerThread, KDefaultStackSize, (TAny*)gServerPinningState); |
|
623 serverInfo.SetPaging(TThreadCreateInfo::EUnpaged); |
|
624 serverInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize); |
|
625 RThread serverThread; |
|
626 test_KErrNone(serverThread.Create(serverInfo)); |
|
627 TRequestStatus serverStat; |
|
628 serverThread.Logon(serverStat); |
|
629 serverThread.Resume(); |
|
630 |
|
631 // Wait for the server to start and then create a session to it. |
|
632 gSem.Wait(); |
|
633 RSession session; |
|
634 test_KErrNone(session.PublicCreateSession(_L("CTestServer"),5)); |
|
635 |
|
636 for ( TUint clientTest = CTestSession::ETestPinAll; |
|
637 clientTest <= CTestSession::ETestPinDefault && !exitFailure; |
|
638 clientTest++) |
|
639 { |
|
640 // Create the client thread it needs to have a paged stack and heap. |
|
641 TThreadCreateInfo clientInfo(_L("Client Thread"), ClientThread, 10 * gPageSize, (TAny*)clientTest); |
|
642 clientInfo.SetPaging(TThreadCreateInfo::EPaged); |
|
643 clientInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize); |
|
644 RThread clientThread; |
|
645 test_KErrNone(clientThread.Create(clientInfo)); |
|
646 |
|
647 TRequestStatus clientStat; |
|
648 clientThread.Logon(clientStat); |
|
649 clientThread.Resume(); |
|
650 |
|
651 // Wait for the client thread to end. |
|
652 User::WaitForRequest(clientStat); |
|
653 |
|
654 // If all the descriptor arguments were not pinned then the client |
|
655 // thread should have been panicked. |
|
656 TBool expectPanic = (clientTest == CTestSession::ETestPinAll || |
|
657 clientTest == CTestSession::ETestPinWritable || |
|
658 clientTest == CTestSession::ETestPinOOM )? 0 : 1; |
|
659 expectPanic = !UpdateExpected(!expectPanic); |
|
660 |
|
661 TInt exitReason = clientThread.ExitReason(); |
|
662 TInt exitType = clientThread.ExitType(); |
|
663 if (expectPanic) |
|
664 { |
|
665 if (exitType != EExitPanic || |
|
666 exitReason != EIllegalFunctionForRealtimeThread || |
|
667 clientThread.ExitCategory() != _L("KERN-EXEC")) |
|
668 {// Thread didn't panic as expected. |
|
669 exitFailure = ETrue; |
|
670 } |
|
671 } |
|
672 else |
|
673 { |
|
674 if (exitType != EExitKill || exitReason != KErrNone) |
|
675 {// Thread didn't exit gracefully as expected. |
|
676 exitFailure = ETrue; |
|
677 } |
|
678 } |
|
679 CLOSE_AND_WAIT(clientThread); |
|
680 } |
|
681 |
|
682 test.Next(_L("Test client sending message to closed server")); |
|
683 TThreadCreateInfo clientInfo(_L("Client Thread"), ClientThread, 10 * gPageSize, (TAny*)CTestSession::ETestDeadServer); |
|
684 clientInfo.SetPaging(TThreadCreateInfo::EPaged); |
|
685 clientInfo.SetCreateHeap(KHeapMinSize, KHeapMaxSize); |
|
686 RThread clientThread; |
|
687 test_KErrNone(clientThread.Create(clientInfo)); |
|
688 TRequestStatus clientStat; |
|
689 clientThread.Logon(clientStat); |
|
690 clientThread.Resume(); |
|
691 gSem.Wait(); |
|
692 |
|
693 // Signal to stop ActiveScheduler and wait for server to stop. |
|
694 session.PublicSendReceive(CTestSession::EStop, TIpcArgs()); |
|
695 session.Close(); |
|
696 User::WaitForRequest(serverStat); |
|
697 if (serverThread.ExitType() != EExitKill) |
|
698 { |
|
699 test.Printf(_L("!!Server thread did something bizarre %d"), serverThread.ExitReason()); |
|
700 } |
|
701 |
|
702 gSem1.Signal(); |
|
703 User::WaitForRequest(clientStat); |
|
704 test_Equal(EExitKill, clientThread.ExitType()); |
|
705 test_Equal(KErrServerTerminated, clientThread.ExitReason()); |
|
706 |
|
707 CLOSE_AND_WAIT(clientThread); |
|
708 CLOSE_AND_WAIT(serverThread); |
|
709 CLOSE_AND_WAIT(gSem); |
|
710 CLOSE_AND_WAIT(gSem1); |
|
711 } |
|
712 test(!exitFailure); |
|
713 |
|
714 test.Next(_L("Test server setting pinning policy after server started")); |
|
715 RThread serverThread; |
|
716 test_KErrNone(serverThread.Create(_L("Server Thread"),ServerThread,KDefaultStackSize,KHeapMinSize,KHeapMaxSize, (TAny*)gServerPinningState)); |
|
717 TRequestStatus serverStat; |
|
718 serverThread.Logon(serverStat); |
|
719 serverThread.Resume(); |
|
720 // The server should have panicked with E32USER-CBase 106. |
|
721 User::WaitForRequest(serverStat); |
|
722 TInt exitReason = serverThread.ExitReason(); |
|
723 TInt exitType = serverThread.ExitType(); |
|
724 test_Equal(EExitPanic, exitType); |
|
725 test_Equal(ECServer2InvalidSetPin, exitReason); |
|
726 if (_L("E32USER-CBase") != serverThread.ExitCategory()) |
|
727 test(0); |
|
728 CLOSE_AND_WAIT(serverThread); |
|
729 |
|
730 test.End(); |
|
731 |
|
732 // Set JIT back to original state. |
|
733 User::SetJustInTime(justInTime); |
|
734 |
|
735 return (KErrNone); |
|
736 } |