Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\server\t_open.cpp
//
//
#include <f32file.h>
#include <e32test.h>
#include "t_server.h"
GLDEF_D RTest test(_L("T_OPEN"));
LOCAL_D TFileName gBatchFile;
LOCAL_D TBool gRunByBatch=EFalse;
TFileName filename1=_L("Z:\\TEST\\T_FSRV.CPP");
TFileName filename2=_L("Z:\\TEST\\T_FILE.CPP");
TFileName dirname1=_L("Z:\\TEST\\*.XDE");
LOCAL_C void Test0()
//
// Scan for open files - no sessions
//
{
test.Next(_L("Scan for open files with no sessions open"));
CFileList* list;
TOpenFileScan fileScan(TheFs);
fileScan.NextL(list);
if (list==NULL)
return;
TInt count=list->Count();
if (count==1)
{
gRunByBatch=ETrue;
gBatchFile=(*list)[0].iName;
delete list;
fileScan.NextL(list);
if (list==NULL)
return;
count=list->Count();
}
while (count--)
{
TEntry entry=(*list)[count];
test.Printf(_L("%d) EntryName = %S\n"),count,&entry.iName);
}
test.Printf(_L("Test will fail unless files are closed.\n"));
test(0);
//test.Printf(_L("Press any key ...\n"));
//test.Getch();
}
LOCAL_C void Test1()
//
// Test OpenFileScan
//
{
test.Next(_L("Scan for open files - one session only"));
RFile file1,file2,file3;
TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(TheFs,filename2,EFileRead);
test(r==KErrNone);
r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
CFileList* list=NULL;
TOpenFileScan fileScan(TheFs);
TRAP(r,fileScan.NextL(list));
test(r==KErrNone);
if (gRunByBatch)
{
test(list!=NULL);
test(list->Count()==1);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L(".BAT"))>=0);
delete list;
fileScan.NextL(list);
}
test(list!=NULL);
TInt count=list->Count();
test(count==3);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
TThreadId threadId=fileScan.ThreadId();
RThread current;
TThreadId currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list==NULL);
file1.Close();
file2.Close();
file3.Close();
}
LOCAL_C void Test2()
//
// Test openfilescan - empty, full, empty.
//
{
test.Next(_L("Scan for open files - empty sessions"));
RFs fs1,fs2,fs3,fs4;
TInt r=fs1.Connect();
test(r==KErrNone);
r=fs2.Connect();
test(r==KErrNone);
r=fs3.Connect();
test(r==KErrNone);
r=fs4.Connect();
test(r==KErrNone);
RFile file1,file2,file3;
r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(fs2,filename2,EFileRead);
test(r==KErrNone);
r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
CFileList* list;
TOpenFileScan fileScan(TheFs);
fileScan.NextL(list);
if (gRunByBatch)
{
test(list!=NULL);
test(list->Count()==1);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L(".BAT"))>=0);
delete list;
fileScan.NextL(list);
}
test(list!=NULL);
TInt count=list->Count();
test(count==3);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
TThreadId threadId=fileScan.ThreadId();
RThread current;
TThreadId currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list==NULL);
file1.Close();
file2.Close();
file3.Close();
fs1.Close();
fs2.Close();
fs3.Close();
fs4.Close();
}
LOCAL_C void Test3()
//
// Test openfilescan - empty, full, empty full
//
{
test.Next(_L("Scan for open files - multiple sessions"));
RFs fs1,fs2,fs3,fs4;
TInt r=fs1.Connect();
test(r==KErrNone);
r=fs2.Connect();
test(r==KErrNone);
r=fs3.Connect();
test(r==KErrNone);
r=fs4.Connect();
test(r==KErrNone);
RFile file1,file2,file3;
r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(fs2,filename2,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file1.Open(fs4,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(fs4,filename2,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file3.Open(fs4,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
CFileList* list;
TOpenFileScan fileScan(TheFs);
fileScan.NextL(list);
if (gRunByBatch)
{
test(list!=NULL);
test(list->Count()==1);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L(".BAT"))>=0);
delete list;
fileScan.NextL(list);
}
test(list!=NULL);
TInt count=list->Count();
test(count==3);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
TThreadId threadId=fileScan.ThreadId();
RThread current;
TThreadId currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list!=NULL);
count=list->Count();
test(count==3);
entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
threadId=fileScan.ThreadId();
currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list==NULL);
file1.Close();
file2.Close();
file3.Close();
fs1.Close();
fs2.Close();
fs3.Close();
fs4.Close();
}
LOCAL_C void Test4()
//
// Test openfilescan - rdirs, empty, full, empty rdirs.
//
{
test.Next(_L("Scan for open files - check RDir sessions are ignored"));
RFs fs1,fs2,fs3,fs4;
TInt r=fs1.Connect();
test(r==KErrNone);
r=fs2.Connect();
test(r==KErrNone);
r=fs3.Connect();
test(r==KErrNone);
r=fs4.Connect();
test(r==KErrNone);
RDir dir1,dir2,dir3,dir4;
r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
RFile file1,file2,file3;
r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(fs2,filename2,EFileRead);
test(r==KErrNone);
r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
RDir dir5,dir6,dir7,dir8;
r=dir5.Open(fs4,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir6.Open(fs4,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir7.Open(fs4,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir8.Open(fs4,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
CFileList* list;
TOpenFileScan fileScan(TheFs);
fileScan.NextL(list);
if (gRunByBatch)
{
test(list!=NULL);
test(list->Count()==1);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L(".BAT"))>=0);
delete list;
fileScan.NextL(list);
}
test(list!=NULL);
TInt count=list->Count();
test(count==3);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
TThreadId threadId=fileScan.ThreadId();
RThread current;
TThreadId currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list==NULL);
file1.Close();
file2.Close();
file3.Close();
dir1.Close(); dir2.Close();
dir3.Close(); dir4.Close();
dir5.Close(); dir6.Close();
dir7.Close(); dir8.Close();
fs1.Close(); fs2.Close();
fs3.Close(); fs4.Close();
}
LOCAL_C void Test5()
//
// Test OpenFileScan
//
{
test.Next(_L("Scan for open files - mixed RDirs and RFiles"));
RFile file1,file2,file3;
TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
r=file2.Open(TheFs,filename2,EFileRead);
test(r==KErrNone);
r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
test(r==KErrNone);
RDir dir1,dir2,dir3,dir4;
r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported);
test(r==KErrNone);
CFileList* list;
TOpenFileScan fileScan(TheFs);
fileScan.NextL(list);
if (gRunByBatch)
{
test(list!=NULL);
test(list->Count()==1);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L(".BAT"))>=0);
delete list;
fileScan.NextL(list);
}
test(list!=NULL);
TInt count=list->Count();
test(count==3);
TEntry entry=(*list)[0];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
entry=(*list)[1];
test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
entry=(*list)[2];
test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
TThreadId threadId=fileScan.ThreadId();
RThread current;
TThreadId currentId=current.Id();
test(threadId==currentId);
delete list;
fileScan.NextL(list);
test(list==NULL);
file1.Close();
file2.Close();
file3.Close();
dir1.Close();
dir2.Close();
dir3.Close();
dir4.Close();
}
NONSHARABLE_STRUCT(TThreadData)
//
// Encapsulates the data required by the worker thread.
//
{
// Thread identifier for debug output
TInt iNumber;
// ID of the thread that started the worker thread, and the
// worker thread itself
TThreadId iMain;
TThreadId iWorker;
// Request status object of the parent thread, used for signalling
TRequestStatus* iStatus;
// Name of the file the parent thread requires this thread to open
TFileName iFilename;
// Number of files opened by the thread;
TInt iNumFiles;
};
LOCAL_C TInt WorkerThread(TAny* aParameter)
//
// This function is designed to run as a separate thread in order to verify the
// fix for DEF062875.
//
// When the thread is started it opens the file specified in the startup
// parameter, signals the main thread and then suspends. Once the main thread
// has completed its checking the worker thread is resumed and allowed to run
// to completion.
//
// @param aParameter Thread specific data supplied by the main thread when the
// worker thread is started. The data may be accessed by
// casting this pointer to a TThreadData*
//
{
// Can't use our global "test" object here
RTest myTest(_L("Worker thread"));
// Extract the parameters that this thread will need to use
TThreadData* threadData = (TThreadData*)aParameter;
RThread current;
TThreadId currentId = current.Id();
myTest.Printf(_L("WORK%d: Worker thread %d started\n"), threadData->iNumber, threadData->iNumber);
myTest.Printf(_L("WORK%d: File: %S\n"), threadData->iNumber, &threadData->iFilename);
myTest.Printf(_L("WORK%d: Thread: %d\n"), threadData->iNumber, (TUint)currentId);
myTest.Printf(_L("WORK%d: Parent: %d\n"), threadData->iNumber, (TUint)threadData->iMain);
// Open the file specified by the parameter passed to us from the main
// thread
RFs myFs;
myFs.Connect();
RFile file;
User::LeaveIfError(file.Open(myFs, threadData->iFilename, EFileRead | EFileShareReadersOnly));
// Signal the parent thread to continue then wait
myTest.Printf(_L("WORK%d: Signalling parent thread\n"), threadData->iNumber);
RThread parent;
User::LeaveIfError(parent.Open(threadData->iMain));
parent.RequestComplete(threadData->iStatus, KErrNone);
myTest.Printf(_L("WORK%d: Waiting for parent thread to restart us\n"), threadData->iNumber);
current.Suspend();
// Tidy up
myTest.Printf(_L("WORK%d: Closing file\n"), threadData->iNumber);
file.Close();
return KErrNone;
}
LOCAL_C void TestDEF062875()
//
// Verify that TOpenFileScan::ThreadId() returns the ID of the thread that
// opened the file.
//
// The object of the exercise here is to create several worker threads, each
// one will open a file, signal the main thread and then suspend. Once all
// the worker threads have suspended the main thread then uses
// TOpenFileScan::NextL() to verify that the thread IDs correspond to the
// worker threads that opened each file and not that of the main thread.
//
// The worker threads are then restarted and allowed to terminate naturally by
// running to completion
//
{
test.Start(_L("Test TOpenFileScan::ThreadId()"));
const TInt KHeapSize = 32768;
RThread thread1;
RThread thread2;
TRequestStatus status1;
TRequestStatus status2;
TThreadId id = RThread().Id();
TThreadData threadData[3];
threadData[0].iNumber = 0;
threadData[0].iMain = id;
threadData[0].iWorker = id;
threadData[0].iStatus = 0;
threadData[0].iFilename = filename1;
threadData[0].iNumFiles = 2;
threadData[1].iNumber = 1;
threadData[1].iMain = id;
threadData[1].iStatus = &status1;
threadData[1].iFilename = filename1;
threadData[1].iNumFiles = 1;
threadData[2].iNumber = 2;
threadData[2].iMain = id;
threadData[2].iStatus = &status2;
threadData[2].iFilename = filename2;
threadData[2].iNumFiles = 1;
TInt numThreads = sizeof(threadData)/sizeof(threadData[0]);
// Open the files in the MAIN thread.
RFile file1;
User::LeaveIfError(file1.Open(TheFs, filename1, EFileRead | EFileShareReadersOnly));
RFile file2;
User::LeaveIfError(file2.Open(TheFs, filename2, EFileRead | EFileShareReadersOnly));
// Create the first worker thread
test.Printf(_L("MAIN: Creating worker threads\n"));
thread1.Create(_L("WorkerThread1"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[1]);
threadData[1].iWorker = thread1.Id();
// Start it and wait for it to suspend
thread1.Logon(status1);
thread1.Resume();
test.Printf(_L("MAIN: Waiting for worker thread 1\n"));
User::WaitForRequest(status1);
// Create the second worker thread
thread2.Create(_L("WorkerThread2"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[2]);
threadData[2].iWorker = thread2.Id();
// Start it and wait for it to suspend
thread2.Logon(status2);
thread2.Resume();
test.Printf(_L("MAIN: Waiting for worker thread 2\n"));
User::WaitForRequest(status2);
// Obtain a list of open files. At this point we should have a single open
// file, as opened by our worker thread. The thread ID reported by
// TOpenFileScan should be that of our worker thread rather than the main
// thread.
test.Printf(_L("MAIN: Verifying thread ID of open file(s)\n"));
CFileList* list;
TOpenFileScan fileScan(TheFs);
TInt count = 0;
FOREVER
{
fileScan.NextL(list);
// The NULL list indicates we've run out of sessions.
if(!list)
{
break;
}
TThreadId threadId=fileScan.ThreadId();
TThreadData* data = 0;
for (count = 0; count < numThreads; count++)
{
if (threadId == threadData[count].iWorker)
{
data = &threadData[count];
break;
}
}
if (data)
{
test.Next(_L("Check number of open files..."));
test.Printf(_L("MAIN: Number of open files: %d (expecting %d)\n"), list->Count(), data->iNumFiles);
test(list->Count() == threadData[count].iNumFiles);
test.Next(_L("Check TThreadIds..."));
test.Printf(_L("MAIN: Main thread ID : %d\n"), (TUint)data->iMain);
test.Printf(_L("MAIN: Worker thread ID: %d\n"), (TUint)data->iWorker);
test.Printf(_L("MAIN: File thread ID : %d\n"), (TUint)threadId);
TInt loop = 0;
for (loop = 0; loop < list->Count(); loop++)
{
const TEntry& theEntry = (*list)[loop];
test.Printf(_L(" "));
test.Printf(theEntry.iName);
test.Printf(_L("\n"));
}
}
else
{
test.Printf(_L("Ignored thread %d\n"), (TUint)threadId);
}
delete list;
list = 0;
test.Printf(_L("\n"));
}
// Signal the two worker threads to tidy up and run to normal termination
test.Printf(_L("MAIN: Signalling worker thread 1\n"));
thread1.Logon(status1);
thread1.Resume();
User::WaitForRequest(status1);
test.Printf(_L("MAIN: Signalling worker thread 2\n"));
thread2.Logon(status2);
thread2.Resume();
User::WaitForRequest(status2);
// Tidy up and finish
test.Printf(_L("MAIN: Closing worker thread 1\n"));
thread1.Close();
test.Printf(_L("MAIN: Closing worker thread 2\n"));
thread2.Close();
file1.Close();
file2.Close();
test.End();
}
GLDEF_C void CallTestsL()
//
// Call tests that may leave
//
{
filename1[0] = gExeFileName[0];
filename2[0] = gExeFileName[0];
dirname1[0] = gExeFileName[0];
Test0();
Test1();
Test2();
Test3();
Test4();
Test5();
TestDEF062875();
}