sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Test code for multi-threaded file descriptors etc. sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include // for RDebug sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: extern "C" { sl@0: #include "CTEST.H" sl@0: } sl@0: sl@0: #include // for multi-threading control sl@0: sl@0: sl@0: #ifdef _DEBUG sl@0: #define ttest_Next(testname) \ sl@0: RDebug::Print(_L("t%d: %s"), (TInt)thread, testname); \ sl@0: printf("t%d: ", (TInt)thread); \ sl@0: test_Next(testname) sl@0: #else sl@0: //don't use RDebug::Print when it's a release build sl@0: #define ttest_Next(testname) test_Next(testname) sl@0: #endif sl@0: sl@0: test_Data; sl@0: RSemaphore waiting[2]; sl@0: sl@0: void over(TInt n) sl@0: { sl@0: // RDebug::Print(_L("Over(%d)"),n); sl@0: waiting[1-n].Signal(); sl@0: waiting[n].Wait(); sl@0: } sl@0: sl@0: #define THREAD0 if (thread==0) sl@0: #define THREAD1 if (thread==(TAny*)1) sl@0: #define OVER over((TInt)thread) sl@0: sl@0: // Shared variables sl@0: sl@0: int fd; sl@0: sl@0: /** sl@0: Interleaved test code sl@0: sl@0: @SYMTestCaseID SYSLIB-STDLIB-CT-1071 sl@0: @SYMTestCaseDesc Tests for multi-threaded file descriptors sl@0: @SYMTestPriority High sl@0: @SYMTestActions Run threads to open,read,close test files sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: TInt testfunction(TAny* thread) sl@0: { sl@0: int n; sl@0: char *p; sl@0: ttest_Next("Entering testfunction"); sl@0: // sl@0: ttest_Next("Competing console reads - press 'A' then 'B'..."); sl@0: fflush(stdout); sl@0: int c=getchar(); sl@0: fprintf(stderr, "t%d: read char %d\r\n", thread, c); sl@0: // sl@0: THREAD0 sl@0: { sl@0: waiting[0].Wait(); // until Thread1 says OVER sl@0: ttest_Next("Create test file"); sl@0: fd=open("c:\\testfile", O_RDWR+O_CREAT+O_TRUNC, 0777); sl@0: test_ok(fd>=0); sl@0: } sl@0: // sl@0: OVER; sl@0: ttest_Next("Get the sequencing sorted out..."); sl@0: OVER; sl@0: THREAD1 sl@0: { sl@0: ttest_Next("Write to test file"); sl@0: p="Hello from thread 1\r\n"; sl@0: n=write(fd,p,strlen(p)); sl@0: test_ok(n==strlen(p)); sl@0: } sl@0: THREAD0 sl@0: { sl@0: ttest_Next("Close test file"); sl@0: close(fd); sl@0: } sl@0: OVER; sl@0: THREAD1 sl@0: { sl@0: ttest_Next("Reopen test file"); sl@0: fd=open("c:\\testfile",O_RDONLY,0); sl@0: test_ok(fd>=0); sl@0: } sl@0: THREAD0 sl@0: { sl@0: ttest_Next("Read from test file"); sl@0: char buf[80]; sl@0: buf[6]='\0'; sl@0: n=read(fd,buf,6); sl@0: test_ok(n==6); sl@0: test(strncmp(buf,"Hello ",6)==0); sl@0: printf("Read >%s<... \r\n",buf); sl@0: fflush(stdout); sl@0: } sl@0: OVER; sl@0: THREAD1 sl@0: { sl@0: ttest_Next("Read from test file"); sl@0: close(0); sl@0: n=dup2(fd,0); sl@0: test(n>=0); // associate stdin with "testfile" sl@0: char buf[80]; sl@0: p=fgets(buf,80,stdin); sl@0: test_ok(p==buf); sl@0: fprintf(stderr, "Read >%s<\r\n", buf); sl@0: } sl@0: THREAD0 sl@0: { sl@0: ttest_Next("Close test file"); sl@0: close(fd); sl@0: } sl@0: OVER; sl@0: ttest_Next("Completed testfunction"); sl@0: waiting[0].Signal(); // allow thread0 to continue sl@0: waiting[1].Signal(); // allow thread1 to continue sl@0: return 0; sl@0: } sl@0: sl@0: // Thread management - main thread is thread0 sl@0: sl@0: void init_threads() sl@0: { sl@0: waiting[0].CreateLocal(0); sl@0: waiting[1].CreateLocal(0); sl@0: sl@0: RThread thread1; sl@0: TInt err=thread1.Create(_L("Thread1"),testfunction,0x10000,NULL,(TAny*)1); sl@0: test(err==KErrNone); sl@0: test_Next("Starting thread1"); sl@0: thread1.Resume(); sl@0: test_Next("entering main test..."); sl@0: } sl@0: sl@0: int main(int argc, char *argv[]) sl@0: { sl@0: // SpawnPosixServerThread(); - provided by MCRT0.OBJ sl@0: sl@0: start_redirection_server(); sl@0: sl@0: test_Title("TMTHREAD"); sl@0: init_threads(); sl@0: testfunction(0); sl@0: test_Close(); sl@0: return KErrNone; sl@0: }