|
1 // Copyright (c) 1996-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 // f32test\server\t_open.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include <f32file.h> |
|
19 #include <e32test.h> |
|
20 #include "t_server.h" |
|
21 |
|
22 GLDEF_D RTest test(_L("T_OPEN")); |
|
23 |
|
24 LOCAL_D TFileName gBatchFile; |
|
25 LOCAL_D TBool gRunByBatch=EFalse; |
|
26 |
|
27 TFileName filename1=_L("Z:\\TEST\\T_FSRV.CPP"); |
|
28 TFileName filename2=_L("Z:\\TEST\\T_FILE.CPP"); |
|
29 TFileName dirname1=_L("Z:\\TEST\\*.XDE"); |
|
30 |
|
31 |
|
32 LOCAL_C void Test0() |
|
33 // |
|
34 // Scan for open files - no sessions |
|
35 // |
|
36 { |
|
37 |
|
38 test.Next(_L("Scan for open files with no sessions open")); |
|
39 CFileList* list; |
|
40 TOpenFileScan fileScan(TheFs); |
|
41 fileScan.NextL(list); |
|
42 if (list==NULL) |
|
43 return; |
|
44 TInt count=list->Count(); |
|
45 if (count==1) |
|
46 { |
|
47 gRunByBatch=ETrue; |
|
48 gBatchFile=(*list)[0].iName; |
|
49 delete list; |
|
50 fileScan.NextL(list); |
|
51 if (list==NULL) |
|
52 return; |
|
53 count=list->Count(); |
|
54 } |
|
55 while (count--) |
|
56 { |
|
57 TEntry entry=(*list)[count]; |
|
58 test.Printf(_L("%d) EntryName = %S\n"),count,&entry.iName); |
|
59 } |
|
60 test.Printf(_L("Test will fail unless files are closed.\n")); |
|
61 test(0); |
|
62 //test.Printf(_L("Press any key ...\n")); |
|
63 //test.Getch(); |
|
64 } |
|
65 |
|
66 LOCAL_C void Test1() |
|
67 // |
|
68 // Test OpenFileScan |
|
69 // |
|
70 { |
|
71 |
|
72 test.Next(_L("Scan for open files - one session only")); |
|
73 |
|
74 RFile file1,file2,file3; |
|
75 |
|
76 TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly); |
|
77 test(r==KErrNone); |
|
78 |
|
79 r=file2.Open(TheFs,filename2,EFileRead); |
|
80 test(r==KErrNone); |
|
81 |
|
82 r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly); |
|
83 test(r==KErrNone); |
|
84 |
|
85 CFileList* list=NULL; |
|
86 TOpenFileScan fileScan(TheFs); |
|
87 TRAP(r,fileScan.NextL(list)); |
|
88 test(r==KErrNone); |
|
89 |
|
90 if (gRunByBatch) |
|
91 { |
|
92 test(list!=NULL); |
|
93 test(list->Count()==1); |
|
94 TEntry entry=(*list)[0]; |
|
95 test(entry.iName.FindF(_L(".BAT"))>=0); |
|
96 delete list; |
|
97 fileScan.NextL(list); |
|
98 } |
|
99 |
|
100 |
|
101 test(list!=NULL); |
|
102 TInt count=list->Count(); |
|
103 test(count==3); |
|
104 TEntry entry=(*list)[0]; |
|
105 |
|
106 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
107 entry=(*list)[1]; |
|
108 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
109 entry=(*list)[2]; |
|
110 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
111 TThreadId threadId=fileScan.ThreadId(); |
|
112 RThread current; |
|
113 TThreadId currentId=current.Id(); |
|
114 test(threadId==currentId); |
|
115 delete list; |
|
116 |
|
117 fileScan.NextL(list); |
|
118 test(list==NULL); |
|
119 |
|
120 file1.Close(); |
|
121 file2.Close(); |
|
122 file3.Close(); |
|
123 } |
|
124 |
|
125 LOCAL_C void Test2() |
|
126 // |
|
127 // Test openfilescan - empty, full, empty. |
|
128 // |
|
129 { |
|
130 |
|
131 |
|
132 test.Next(_L("Scan for open files - empty sessions")); |
|
133 |
|
134 RFs fs1,fs2,fs3,fs4; |
|
135 TInt r=fs1.Connect(); |
|
136 test(r==KErrNone); |
|
137 r=fs2.Connect(); |
|
138 test(r==KErrNone); |
|
139 r=fs3.Connect(); |
|
140 test(r==KErrNone); |
|
141 r=fs4.Connect(); |
|
142 test(r==KErrNone); |
|
143 |
|
144 RFile file1,file2,file3; |
|
145 |
|
146 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
147 test(r==KErrNone); |
|
148 |
|
149 r=file2.Open(fs2,filename2,EFileRead); |
|
150 test(r==KErrNone); |
|
151 |
|
152 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
153 test(r==KErrNone); |
|
154 |
|
155 CFileList* list; |
|
156 TOpenFileScan fileScan(TheFs); |
|
157 fileScan.NextL(list); |
|
158 |
|
159 if (gRunByBatch) |
|
160 { |
|
161 test(list!=NULL); |
|
162 test(list->Count()==1); |
|
163 TEntry entry=(*list)[0]; |
|
164 test(entry.iName.FindF(_L(".BAT"))>=0); |
|
165 delete list; |
|
166 fileScan.NextL(list); |
|
167 } |
|
168 |
|
169 test(list!=NULL); |
|
170 TInt count=list->Count(); |
|
171 test(count==3); |
|
172 TEntry entry=(*list)[0]; |
|
173 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
174 entry=(*list)[1]; |
|
175 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
176 entry=(*list)[2]; |
|
177 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
178 TThreadId threadId=fileScan.ThreadId(); |
|
179 RThread current; |
|
180 TThreadId currentId=current.Id(); |
|
181 test(threadId==currentId); |
|
182 delete list; |
|
183 |
|
184 fileScan.NextL(list); |
|
185 test(list==NULL); |
|
186 |
|
187 file1.Close(); |
|
188 file2.Close(); |
|
189 file3.Close(); |
|
190 fs1.Close(); |
|
191 fs2.Close(); |
|
192 fs3.Close(); |
|
193 fs4.Close(); |
|
194 } |
|
195 |
|
196 LOCAL_C void Test3() |
|
197 // |
|
198 // Test openfilescan - empty, full, empty full |
|
199 // |
|
200 { |
|
201 |
|
202 test.Next(_L("Scan for open files - multiple sessions")); |
|
203 |
|
204 RFs fs1,fs2,fs3,fs4; |
|
205 TInt r=fs1.Connect(); |
|
206 test(r==KErrNone); |
|
207 r=fs2.Connect(); |
|
208 test(r==KErrNone); |
|
209 r=fs3.Connect(); |
|
210 test(r==KErrNone); |
|
211 r=fs4.Connect(); |
|
212 test(r==KErrNone); |
|
213 |
|
214 RFile file1,file2,file3; |
|
215 |
|
216 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
217 test(r==KErrNone); |
|
218 |
|
219 r=file2.Open(fs2,filename2,EFileRead|EFileShareReadersOnly); |
|
220 test(r==KErrNone); |
|
221 |
|
222 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
223 test(r==KErrNone); |
|
224 |
|
225 r=file1.Open(fs4,filename1,EFileRead|EFileShareReadersOnly); |
|
226 test(r==KErrNone); |
|
227 |
|
228 r=file2.Open(fs4,filename2,EFileRead|EFileShareReadersOnly); |
|
229 test(r==KErrNone); |
|
230 |
|
231 r=file3.Open(fs4,filename1,EFileRead|EFileShareReadersOnly); |
|
232 test(r==KErrNone); |
|
233 |
|
234 CFileList* list; |
|
235 TOpenFileScan fileScan(TheFs); |
|
236 fileScan.NextL(list); |
|
237 |
|
238 if (gRunByBatch) |
|
239 { |
|
240 test(list!=NULL); |
|
241 test(list->Count()==1); |
|
242 TEntry entry=(*list)[0]; |
|
243 test(entry.iName.FindF(_L(".BAT"))>=0); |
|
244 delete list; |
|
245 fileScan.NextL(list); |
|
246 } |
|
247 |
|
248 test(list!=NULL); |
|
249 TInt count=list->Count(); |
|
250 test(count==3); |
|
251 TEntry entry=(*list)[0]; |
|
252 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
253 entry=(*list)[1]; |
|
254 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
255 entry=(*list)[2]; |
|
256 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
257 TThreadId threadId=fileScan.ThreadId(); |
|
258 RThread current; |
|
259 TThreadId currentId=current.Id(); |
|
260 test(threadId==currentId); |
|
261 delete list; |
|
262 |
|
263 fileScan.NextL(list); |
|
264 test(list!=NULL); |
|
265 count=list->Count(); |
|
266 test(count==3); |
|
267 entry=(*list)[0]; |
|
268 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
269 entry=(*list)[1]; |
|
270 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
271 entry=(*list)[2]; |
|
272 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
273 threadId=fileScan.ThreadId(); |
|
274 currentId=current.Id(); |
|
275 test(threadId==currentId); |
|
276 delete list; |
|
277 |
|
278 fileScan.NextL(list); |
|
279 test(list==NULL); |
|
280 |
|
281 file1.Close(); |
|
282 file2.Close(); |
|
283 file3.Close(); |
|
284 fs1.Close(); |
|
285 fs2.Close(); |
|
286 fs3.Close(); |
|
287 fs4.Close(); |
|
288 } |
|
289 |
|
290 LOCAL_C void Test4() |
|
291 // |
|
292 // Test openfilescan - rdirs, empty, full, empty rdirs. |
|
293 // |
|
294 { |
|
295 test.Next(_L("Scan for open files - check RDir sessions are ignored")); |
|
296 |
|
297 RFs fs1,fs2,fs3,fs4; |
|
298 TInt r=fs1.Connect(); |
|
299 test(r==KErrNone); |
|
300 r=fs2.Connect(); |
|
301 test(r==KErrNone); |
|
302 r=fs3.Connect(); |
|
303 test(r==KErrNone); |
|
304 r=fs4.Connect(); |
|
305 test(r==KErrNone); |
|
306 |
|
307 RDir dir1,dir2,dir3,dir4; |
|
308 r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
309 test(r==KErrNone); |
|
310 r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
311 test(r==KErrNone); |
|
312 r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
313 test(r==KErrNone); |
|
314 r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
315 test(r==KErrNone); |
|
316 |
|
317 RFile file1,file2,file3; |
|
318 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
319 test(r==KErrNone); |
|
320 r=file2.Open(fs2,filename2,EFileRead); |
|
321 test(r==KErrNone); |
|
322 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly); |
|
323 test(r==KErrNone); |
|
324 |
|
325 RDir dir5,dir6,dir7,dir8; |
|
326 r=dir5.Open(fs4,dirname1,KEntryAttMaskSupported); |
|
327 test(r==KErrNone); |
|
328 r=dir6.Open(fs4,dirname1,KEntryAttMaskSupported); |
|
329 test(r==KErrNone); |
|
330 r=dir7.Open(fs4,dirname1,KEntryAttMaskSupported); |
|
331 test(r==KErrNone); |
|
332 r=dir8.Open(fs4,dirname1,KEntryAttMaskSupported); |
|
333 test(r==KErrNone); |
|
334 |
|
335 CFileList* list; |
|
336 TOpenFileScan fileScan(TheFs); |
|
337 fileScan.NextL(list); |
|
338 |
|
339 if (gRunByBatch) |
|
340 { |
|
341 test(list!=NULL); |
|
342 test(list->Count()==1); |
|
343 TEntry entry=(*list)[0]; |
|
344 test(entry.iName.FindF(_L(".BAT"))>=0); |
|
345 delete list; |
|
346 fileScan.NextL(list); |
|
347 } |
|
348 |
|
349 test(list!=NULL); |
|
350 TInt count=list->Count(); |
|
351 test(count==3); |
|
352 TEntry entry=(*list)[0]; |
|
353 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
354 entry=(*list)[1]; |
|
355 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
356 entry=(*list)[2]; |
|
357 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
358 TThreadId threadId=fileScan.ThreadId(); |
|
359 RThread current; |
|
360 TThreadId currentId=current.Id(); |
|
361 test(threadId==currentId); |
|
362 delete list; |
|
363 |
|
364 fileScan.NextL(list); |
|
365 test(list==NULL); |
|
366 |
|
367 file1.Close(); |
|
368 file2.Close(); |
|
369 file3.Close(); |
|
370 dir1.Close(); dir2.Close(); |
|
371 dir3.Close(); dir4.Close(); |
|
372 dir5.Close(); dir6.Close(); |
|
373 dir7.Close(); dir8.Close(); |
|
374 fs1.Close(); fs2.Close(); |
|
375 fs3.Close(); fs4.Close(); |
|
376 } |
|
377 |
|
378 LOCAL_C void Test5() |
|
379 // |
|
380 // Test OpenFileScan |
|
381 // |
|
382 { |
|
383 |
|
384 test.Next(_L("Scan for open files - mixed RDirs and RFiles")); |
|
385 |
|
386 RFile file1,file2,file3; |
|
387 TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly); |
|
388 test(r==KErrNone); |
|
389 r=file2.Open(TheFs,filename2,EFileRead); |
|
390 test(r==KErrNone); |
|
391 r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly); |
|
392 test(r==KErrNone); |
|
393 |
|
394 RDir dir1,dir2,dir3,dir4; |
|
395 r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
396 test(r==KErrNone); |
|
397 r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
398 test(r==KErrNone); |
|
399 r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
400 test(r==KErrNone); |
|
401 r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported); |
|
402 test(r==KErrNone); |
|
403 |
|
404 CFileList* list; |
|
405 TOpenFileScan fileScan(TheFs); |
|
406 fileScan.NextL(list); |
|
407 |
|
408 if (gRunByBatch) |
|
409 { |
|
410 test(list!=NULL); |
|
411 test(list->Count()==1); |
|
412 TEntry entry=(*list)[0]; |
|
413 test(entry.iName.FindF(_L(".BAT"))>=0); |
|
414 delete list; |
|
415 fileScan.NextL(list); |
|
416 } |
|
417 |
|
418 test(list!=NULL); |
|
419 TInt count=list->Count(); |
|
420 test(count==3); |
|
421 TEntry entry=(*list)[0]; |
|
422 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
423 entry=(*list)[1]; |
|
424 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0); |
|
425 entry=(*list)[2]; |
|
426 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0); |
|
427 TThreadId threadId=fileScan.ThreadId(); |
|
428 RThread current; |
|
429 TThreadId currentId=current.Id(); |
|
430 test(threadId==currentId); |
|
431 delete list; |
|
432 |
|
433 fileScan.NextL(list); |
|
434 test(list==NULL); |
|
435 |
|
436 file1.Close(); |
|
437 file2.Close(); |
|
438 file3.Close(); |
|
439 dir1.Close(); |
|
440 dir2.Close(); |
|
441 dir3.Close(); |
|
442 dir4.Close(); |
|
443 } |
|
444 |
|
445 |
|
446 NONSHARABLE_STRUCT(TThreadData) |
|
447 // |
|
448 // Encapsulates the data required by the worker thread. |
|
449 // |
|
450 { |
|
451 // Thread identifier for debug output |
|
452 TInt iNumber; |
|
453 |
|
454 // ID of the thread that started the worker thread, and the |
|
455 // worker thread itself |
|
456 TThreadId iMain; |
|
457 TThreadId iWorker; |
|
458 |
|
459 // Request status object of the parent thread, used for signalling |
|
460 TRequestStatus* iStatus; |
|
461 |
|
462 // Name of the file the parent thread requires this thread to open |
|
463 TFileName iFilename; |
|
464 |
|
465 // Number of files opened by the thread; |
|
466 TInt iNumFiles; |
|
467 }; |
|
468 |
|
469 |
|
470 LOCAL_C TInt WorkerThread(TAny* aParameter) |
|
471 // |
|
472 // This function is designed to run as a separate thread in order to verify the |
|
473 // fix for DEF062875. |
|
474 // |
|
475 // When the thread is started it opens the file specified in the startup |
|
476 // parameter, signals the main thread and then suspends. Once the main thread |
|
477 // has completed its checking the worker thread is resumed and allowed to run |
|
478 // to completion. |
|
479 // |
|
480 // @param aParameter Thread specific data supplied by the main thread when the |
|
481 // worker thread is started. The data may be accessed by |
|
482 // casting this pointer to a TThreadData* |
|
483 // |
|
484 { |
|
485 // Can't use our global "test" object here |
|
486 RTest myTest(_L("Worker thread")); |
|
487 |
|
488 |
|
489 // Extract the parameters that this thread will need to use |
|
490 TThreadData* threadData = (TThreadData*)aParameter; |
|
491 |
|
492 |
|
493 RThread current; |
|
494 TThreadId currentId = current.Id(); |
|
495 |
|
496 |
|
497 myTest.Printf(_L("WORK%d: Worker thread %d started\n"), threadData->iNumber, threadData->iNumber); |
|
498 myTest.Printf(_L("WORK%d: File: %S\n"), threadData->iNumber, &threadData->iFilename); |
|
499 myTest.Printf(_L("WORK%d: Thread: %d\n"), threadData->iNumber, (TUint)currentId); |
|
500 myTest.Printf(_L("WORK%d: Parent: %d\n"), threadData->iNumber, (TUint)threadData->iMain); |
|
501 |
|
502 |
|
503 // Open the file specified by the parameter passed to us from the main |
|
504 // thread |
|
505 RFs myFs; |
|
506 myFs.Connect(); |
|
507 RFile file; |
|
508 User::LeaveIfError(file.Open(myFs, threadData->iFilename, EFileRead | EFileShareReadersOnly)); |
|
509 |
|
510 // Signal the parent thread to continue then wait |
|
511 myTest.Printf(_L("WORK%d: Signalling parent thread\n"), threadData->iNumber); |
|
512 RThread parent; |
|
513 User::LeaveIfError(parent.Open(threadData->iMain)); |
|
514 parent.RequestComplete(threadData->iStatus, KErrNone); |
|
515 |
|
516 |
|
517 myTest.Printf(_L("WORK%d: Waiting for parent thread to restart us\n"), threadData->iNumber); |
|
518 current.Suspend(); |
|
519 |
|
520 |
|
521 // Tidy up |
|
522 myTest.Printf(_L("WORK%d: Closing file\n"), threadData->iNumber); |
|
523 file.Close(); |
|
524 |
|
525 |
|
526 return KErrNone; |
|
527 } |
|
528 |
|
529 |
|
530 LOCAL_C void TestDEF062875() |
|
531 // |
|
532 // Verify that TOpenFileScan::ThreadId() returns the ID of the thread that |
|
533 // opened the file. |
|
534 // |
|
535 // The object of the exercise here is to create several worker threads, each |
|
536 // one will open a file, signal the main thread and then suspend. Once all |
|
537 // the worker threads have suspended the main thread then uses |
|
538 // TOpenFileScan::NextL() to verify that the thread IDs correspond to the |
|
539 // worker threads that opened each file and not that of the main thread. |
|
540 // |
|
541 // The worker threads are then restarted and allowed to terminate naturally by |
|
542 // running to completion |
|
543 // |
|
544 { |
|
545 test.Start(_L("Test TOpenFileScan::ThreadId()")); |
|
546 |
|
547 const TInt KHeapSize = 32768; |
|
548 |
|
549 RThread thread1; |
|
550 RThread thread2; |
|
551 |
|
552 TRequestStatus status1; |
|
553 TRequestStatus status2; |
|
554 |
|
555 TThreadId id = RThread().Id(); |
|
556 |
|
557 TThreadData threadData[3]; |
|
558 |
|
559 threadData[0].iNumber = 0; |
|
560 threadData[0].iMain = id; |
|
561 threadData[0].iWorker = id; |
|
562 threadData[0].iStatus = 0; |
|
563 threadData[0].iFilename = filename1; |
|
564 threadData[0].iNumFiles = 2; |
|
565 |
|
566 threadData[1].iNumber = 1; |
|
567 threadData[1].iMain = id; |
|
568 threadData[1].iStatus = &status1; |
|
569 threadData[1].iFilename = filename1; |
|
570 threadData[1].iNumFiles = 1; |
|
571 |
|
572 threadData[2].iNumber = 2; |
|
573 threadData[2].iMain = id; |
|
574 threadData[2].iStatus = &status2; |
|
575 threadData[2].iFilename = filename2; |
|
576 threadData[2].iNumFiles = 1; |
|
577 |
|
578 TInt numThreads = sizeof(threadData)/sizeof(threadData[0]); |
|
579 |
|
580 |
|
581 // Open the files in the MAIN thread. |
|
582 RFile file1; |
|
583 User::LeaveIfError(file1.Open(TheFs, filename1, EFileRead | EFileShareReadersOnly)); |
|
584 |
|
585 RFile file2; |
|
586 User::LeaveIfError(file2.Open(TheFs, filename2, EFileRead | EFileShareReadersOnly)); |
|
587 |
|
588 |
|
589 // Create the first worker thread |
|
590 test.Printf(_L("MAIN: Creating worker threads\n")); |
|
591 thread1.Create(_L("WorkerThread1"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[1]); |
|
592 threadData[1].iWorker = thread1.Id(); |
|
593 |
|
594 // Start it and wait for it to suspend |
|
595 thread1.Logon(status1); |
|
596 thread1.Resume(); |
|
597 test.Printf(_L("MAIN: Waiting for worker thread 1\n")); |
|
598 User::WaitForRequest(status1); |
|
599 |
|
600 |
|
601 // Create the second worker thread |
|
602 thread2.Create(_L("WorkerThread2"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[2]); |
|
603 threadData[2].iWorker = thread2.Id(); |
|
604 |
|
605 |
|
606 // Start it and wait for it to suspend |
|
607 thread2.Logon(status2); |
|
608 thread2.Resume(); |
|
609 test.Printf(_L("MAIN: Waiting for worker thread 2\n")); |
|
610 User::WaitForRequest(status2); |
|
611 |
|
612 |
|
613 // Obtain a list of open files. At this point we should have a single open |
|
614 // file, as opened by our worker thread. The thread ID reported by |
|
615 // TOpenFileScan should be that of our worker thread rather than the main |
|
616 // thread. |
|
617 test.Printf(_L("MAIN: Verifying thread ID of open file(s)\n")); |
|
618 CFileList* list; |
|
619 TOpenFileScan fileScan(TheFs); |
|
620 |
|
621 |
|
622 TInt count = 0; |
|
623 FOREVER |
|
624 { |
|
625 fileScan.NextL(list); |
|
626 |
|
627 |
|
628 // The NULL list indicates we've run out of sessions. |
|
629 if(!list) |
|
630 { |
|
631 break; |
|
632 } |
|
633 |
|
634 |
|
635 TThreadId threadId=fileScan.ThreadId(); |
|
636 TThreadData* data = 0; |
|
637 for (count = 0; count < numThreads; count++) |
|
638 { |
|
639 if (threadId == threadData[count].iWorker) |
|
640 { |
|
641 data = &threadData[count]; |
|
642 break; |
|
643 } |
|
644 } |
|
645 |
|
646 |
|
647 if (data) |
|
648 { |
|
649 test.Next(_L("Check number of open files...")); |
|
650 test.Printf(_L("MAIN: Number of open files: %d (expecting %d)\n"), list->Count(), data->iNumFiles); |
|
651 test(list->Count() == threadData[count].iNumFiles); |
|
652 |
|
653 |
|
654 test.Next(_L("Check TThreadIds...")); |
|
655 test.Printf(_L("MAIN: Main thread ID : %d\n"), (TUint)data->iMain); |
|
656 test.Printf(_L("MAIN: Worker thread ID: %d\n"), (TUint)data->iWorker); |
|
657 test.Printf(_L("MAIN: File thread ID : %d\n"), (TUint)threadId); |
|
658 |
|
659 |
|
660 TInt loop = 0; |
|
661 for (loop = 0; loop < list->Count(); loop++) |
|
662 { |
|
663 const TEntry& theEntry = (*list)[loop]; |
|
664 test.Printf(_L(" ")); |
|
665 test.Printf(theEntry.iName); |
|
666 test.Printf(_L("\n")); |
|
667 } |
|
668 } |
|
669 else |
|
670 { |
|
671 test.Printf(_L("Ignored thread %d\n"), (TUint)threadId); |
|
672 } |
|
673 |
|
674 |
|
675 delete list; |
|
676 list = 0; |
|
677 |
|
678 |
|
679 test.Printf(_L("\n")); |
|
680 } |
|
681 |
|
682 |
|
683 // Signal the two worker threads to tidy up and run to normal termination |
|
684 test.Printf(_L("MAIN: Signalling worker thread 1\n")); |
|
685 thread1.Logon(status1); |
|
686 thread1.Resume(); |
|
687 User::WaitForRequest(status1); |
|
688 |
|
689 test.Printf(_L("MAIN: Signalling worker thread 2\n")); |
|
690 thread2.Logon(status2); |
|
691 thread2.Resume(); |
|
692 User::WaitForRequest(status2); |
|
693 |
|
694 |
|
695 // Tidy up and finish |
|
696 test.Printf(_L("MAIN: Closing worker thread 1\n")); |
|
697 thread1.Close(); |
|
698 |
|
699 test.Printf(_L("MAIN: Closing worker thread 2\n")); |
|
700 thread2.Close(); |
|
701 |
|
702 file1.Close(); |
|
703 file2.Close(); |
|
704 |
|
705 test.End(); |
|
706 } |
|
707 |
|
708 |
|
709 GLDEF_C void CallTestsL() |
|
710 // |
|
711 // Call tests that may leave |
|
712 // |
|
713 { |
|
714 filename1[0] = gExeFileName[0]; |
|
715 filename2[0] = gExeFileName[0]; |
|
716 dirname1[0] = gExeFileName[0]; |
|
717 Test0(); |
|
718 Test1(); |
|
719 Test2(); |
|
720 Test3(); |
|
721 Test4(); |
|
722 Test5(); |
|
723 |
|
724 TestDEF062875(); |
|
725 } |