kerneltest/f32test/server/t_open.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}