os/kernelhwsrv/kerneltest/f32test/server/t_open.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}