00001 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 00002 // All rights reserved. 00003 // This component and the accompanying materials are made available 00004 // under the terms of "Eclipse Public License v1.0" 00005 // which accompanies this distribution, and is available 00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html". 00007 // 00008 // Initial Contributors: 00009 // Nokia Corporation - initial contribution. 00010 // 00011 // Contributors: 00012 // 00013 // Description: 00014 // Include Files 00015 // 00016 00017 #include "libpthreadexample.h" 00018 #include <e32base.h> 00019 #include <e32std.h> 00020 #include <e32cons.h> // Console 00021 #include <pthread.h> //Used for all the functions with prefix pthread_ 00022 #include <f32file.h> 00023 #include "unistd.h" //USed for sleep() 00024 00025 // Constants 00026 _LIT(KTestFile,"c:\\newfile.txt"); //Text file as the shared resource 00027 00028 // Global Variables 00029 LOCAL_D CConsoleBase* console; // Write all messages to this 00030 pthread_mutex_t mutex; //mutex 00031 00032 /* 00033 * This function is the routine for threadOne. It writes "one" in the text file. 00034 * A mutex is used to avoid race condition amongst the threads 00035 */ 00036 void *TestFunction1L(void*) 00037 { 00038 // Start a file server session 00039 RFs aFs; 00040 User::LeaveIfError(aFs.Connect()); 00041 00042 RFile file; 00043 pthread_mutex_lock(&mutex); //Lock the mutex for threadone. 00044 TInt pos = 0; 00045 for(int i=0; i<5; i++) 00046 { 00047 //Push the file object on the cleanup stack before doing any file operation which could leave. 00048 CleanupClosePushL(file); 00049 file.Open(aFs,KTestFile,EFileRead|EFileWrite); 00050 00051 _LIT8(KWriteBuf,"One, \n"); 00052 file.Seek(ESeekEnd, pos ); 00053 file.Write(pos ,KWriteBuf); 00054 CleanupStack::PopAndDestroy(&file); 00055 file.Close(); 00056 User::After(1000000); //Wait for 0.1 s to ensure a visible interthreading mechanism 00057 } 00058 aFs.Close(); 00059 pthread_mutex_unlock(&mutex); //Release the mutex . 00060 return NULL; 00061 } 00062 00063 /* 00064 * This function is the routine for threadTwo. It writes "two" in the text file. 00065 * A mutex is used to avoid race condition amongst the threads 00066 */ 00067 void *TestFunction2L(void*) 00068 { 00069 // Start a file server session 00070 RFs aFs; 00071 User::LeaveIfError(aFs.Connect()); 00072 00073 RFile file; 00074 pthread_mutex_lock(&mutex); //Lock the mutex for threadone. 00075 TInt pos = 0; 00076 for(int i=0; i<5; i++) 00077 { 00078 //Push the file object on the cleanup stack before doing any file operation which could leave. 00079 CleanupClosePushL(file); 00080 file.Open(aFs, KTestFile, EFileRead|EFileWrite); 00081 00082 _LIT8(KWriteBuf, "Two, \n"); 00083 file.Seek(ESeekEnd, pos ); 00084 file.Write(pos, KWriteBuf); 00085 CleanupStack::PopAndDestroy(&file); 00086 file.Close(); 00087 User::After(1000000); //Wait for 0.1 s to ensure a visible interthreading mechanism 00088 } 00089 aFs.Close(); 00090 pthread_mutex_unlock(&mutex); 00091 return NULL; 00092 } 00093 00094 /* 00095 * This function is the routine for threadThree. It writes "three" in the text file. 00096 * A mutex is used to avoid race condition amongst the threads 00097 */ 00098 void *TestFunction3L(void*) 00099 { 00100 // Start a file server session 00101 RFs aFs; 00102 User::LeaveIfError(aFs.Connect()); 00103 00104 RFile file; 00105 pthread_mutex_lock(&mutex); 00106 TInt pos = 0; 00107 for(int i=0; i<5;i++ ) 00108 { 00109 //Push the file object on the cleanup stack before doing any file operation which could leave. 00110 CleanupClosePushL(file); 00111 file.Open(aFs,KTestFile,EFileRead|EFileWrite); 00112 00113 _LIT8(KWriteBuf,"Three ,\n"); 00114 file.Seek(ESeekEnd , pos ); 00115 file.Write(pos ,KWriteBuf); 00116 CleanupStack::PopAndDestroy(&file); 00117 file.Close(); 00118 User::After(1000000); //Wait for 0.1 s to ensure a visible interthreading mechanism 00119 } 00120 aFs.Close(); 00121 pthread_mutex_unlock(&mutex); 00122 return NULL; 00123 } 00124 00125 /* 00126 * The following function creates three threads which starts executing as soon as it is created 00127 * it creates a text file which is used as a shared resource . The main thread will wait till 00128 * child threads completes its execution . 00129 */ 00130 int CreateThreadL() 00131 { 00132 //Three threads declared. 00133 pthread_t threadOne; 00134 pthread_t threadTwo; 00135 pthread_t threadThree; 00136 00137 _LIT(KMain ,"in main\n" ); 00138 console->Write(KMain); 00139 //Start a file server session 00140 RFs aFs; 00141 User::LeaveIfError(aFs.Connect()); 00142 00143 //Create a text file which can be used as a shared resource. 00144 RFile file; 00145 CleanupClosePushL(file); 00146 file.Create(aFs ,KTestFile,EFileRead|EFileWrite); 00147 CleanupStack::PopAndDestroy(&file); 00148 file.Close(); 00149 aFs.Close(); 00150 //Create and initialize mutex for synchronization 00151 if((pthread_mutex_init(&mutex,NULL)) != 0) 00152 { 00153 return -1; 00154 } 00155 00156 //Create threadOne.. thread is in running state. 00157 TInt err1 = pthread_create(&threadOne,NULL,TestFunction1L, NULL); 00158 User::LeaveIfError(err1); 00159 _LIT(KThreadOneCreated , "ThreadOne created\n"); 00160 console->Write(KThreadOneCreated); 00161 00162 //Create threadTwo.. thread is in running state. 00163 TInt err2 = pthread_create(&threadTwo,NULL,TestFunction2L, NULL); 00164 User::LeaveIfError(err2); 00165 _LIT(KThreadTwoCreated , "ThreadTwo created\n"); 00166 console->Write(KThreadTwoCreated); 00167 00168 //Create threadThree.. thread is in running state. 00169 TInt err3 = pthread_create(&threadThree,NULL,TestFunction3L, NULL); 00170 User::LeaveIfError(err3); 00171 _LIT(KThreadThreeCreated , "ThreadThree created\n"); 00172 console->Write(KThreadThreeCreated); 00173 00174 00175 //------Main thread waits for other threads to complete ---- 00176 _LIT(KWait , "Waiting for child threads to complete execution\n"); 00177 console->Write(KWait); 00178 00179 _LIT(KJoinError , "Error in pthread_join()"); 00180 //Main thread waits for threadOne to complete execution 00181 if(pthread_join(threadOne, NULL) != 0) 00182 { 00183 console->Write(KJoinError); 00184 } 00185 else 00186 { 00187 _LIT(KRetThreadOne ,"Returned from threadone\n"); 00188 console->Write(KRetThreadOne); //Control comes to main thread once threadOne completes execution. 00189 } 00190 00191 //Main thread waits for threadTwo to complete execution 00192 if(pthread_join(threadTwo, NULL) != 0) 00193 { 00194 console->Write(KJoinError); 00195 } 00196 else 00197 { 00198 _LIT(KRetThreadTwo ,"Returned from threadtwo\n"); 00199 console->Write(KRetThreadTwo); //Control comes to main thread once threadTwo completes execution. 00200 } 00201 00202 //Main thread waits for threadThree to complete execution 00203 if(pthread_join(threadThree, NULL) != 0) 00204 { 00205 console->Write(KJoinError); 00206 } 00207 else 00208 { 00209 _LIT(KRetThreadThree ,"Returned from threadthree\n"); 00210 console->Write(KRetThreadThree); //Control comes to main thread once threadTwo completes execution. 00211 } 00212 //Clean up 00213 pthread_mutex_destroy(&mutex); 00214 return -1; 00215 } 00216 00217 // Local Functions 00218 00219 LOCAL_C void MainL() 00220 { 00221 _LIT(KHello , "Welcome to the LibpThread example, we will create three threads and use them to print data to \\epoc32\\winscw\\c\\newfile.txt\n\n"); 00222 console->Write(KHello); 00223 CreateThreadL(); 00224 } 00225 00226 LOCAL_C void DoStartL() 00227 { 00228 MainL(); 00229 } 00230 00231 // Global Functions 00232 00233 GLDEF_C TInt E32Main() 00234 { 00235 // Create cleanup stack 00236 __UHEAP_MARK; 00237 CTrapCleanup* cleanup = CTrapCleanup::New(); 00238 // Create output console 00239 _LIT(KTextConsoleTitle, "Console"); 00240 TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen))); 00241 if (createError) 00242 return createError; 00243 // Run application code inside TRAP harness, wait keypress when terminated 00244 TRAPD(mainError, DoStartL()); 00245 _LIT(KTextFailed, " failed, leave code = %d"); 00246 if (mainError) 00247 console->Printf(KTextFailed, mainError); 00248 _LIT(KTextPressAnyKey, " [press any key]\n"); 00249 console->Printf(KTextPressAnyKey); 00250 console->Getch(); 00251 delete console; 00252 delete cleanup; 00253 __UHEAP_MARKEND; 00254 return KErrNone; 00255 } 00256
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.