diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/libpthreadexample_8cpp_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/libpthreadexample_8cpp_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,272 @@ + + +
+ +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 +