examples/PIPS/LibpThreadExample/src/libpthreadexample.cpp

00001 /*
00002 Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008 � list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010 � this list of conditions and the following disclaimer in the documentation
00011 � and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013 � may be used to endorse or promote products derived from this software
00014 � without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: Include Files� 
00028 */
00029   
00030 
00031 
00032 #include "libpthreadexample.h"
00033 #include <e32base.h>
00034 #include <e32std.h>
00035 #include <e32cons.h>    // Console
00036 #include <pthread.h>    //Used for all the functions with prefix pthread_
00037 #include <f32file.h>
00038 #include "unistd.h"             //USed for sleep()
00039 
00040 //  Constants
00041 _LIT(KTestFile,"c:\\newfile.txt");  //Text file as the shared resource
00042 
00043 //  Global Variables
00044 LOCAL_D CConsoleBase* console; // Write all messages to this
00045 pthread_mutex_t  mutex;  //mutex 
00046 
00047 /*
00048  * This function is the routine for threadOne. It writes "one" in the text file. 
00049  * A mutex is used to avoid race condition amongst the threads  
00050  */
00051 void *TestFunction1L(void*)
00052         {
00053         // Start a file server session
00054         RFs aFs;
00055         User::LeaveIfError(aFs.Connect());
00056         
00057         RFile file;
00058         pthread_mutex_lock(&mutex);    //Lock the mutex for threadone. 
00059         TInt pos = 0;      
00060         for(int i=0; i<5; i++)                  
00061                 {
00062                         //Push the file object on the cleanup stack before doing any file operation which could leave. 
00063                         CleanupClosePushL(file); 
00064                         file.Open(aFs,KTestFile,EFileRead|EFileWrite);
00065         
00066                         _LIT8(KWriteBuf,"One, \n");
00067                         file.Seek(ESeekEnd, pos );
00068                         file.Write(pos ,KWriteBuf);
00069                         CleanupStack::PopAndDestroy(&file);
00070                         file.Close();
00071                         User::After(1000000);                   //Wait for 0.1 s to ensure a visible interthreading mechanism
00072                 }
00073                 aFs.Close();
00074                 pthread_mutex_unlock(&mutex);   //Release the mutex . 
00075                 return NULL;
00076         }
00077         
00078 /*
00079  * This function is the routine for threadTwo. It writes "two" in the text file. 
00080  * A mutex is used to avoid race condition amongst the threads  
00081  */
00082 void *TestFunction2L(void*)
00083         {
00084         // Start a file server session
00085         RFs aFs;        
00086         User::LeaveIfError(aFs.Connect());
00087         
00088         RFile file;             
00089         pthread_mutex_lock(&mutex); //Lock the mutex for threadone. 
00090         TInt pos = 0;
00091         for(int i=0; i<5; i++)
00092                 {
00093                         //Push the file object on the cleanup stack before doing any file operation which could leave. 
00094                         CleanupClosePushL(file); 
00095                         file.Open(aFs, KTestFile, EFileRead|EFileWrite);
00096                         
00097                         _LIT8(KWriteBuf, "Two, \n");
00098                         file.Seek(ESeekEnd, pos );
00099                         file.Write(pos, KWriteBuf);
00100                         CleanupStack::PopAndDestroy(&file);
00101                         file.Close();
00102                         User::After(1000000); //Wait for 0.1 s to ensure a visible interthreading mechanism
00103                 }       
00104         aFs.Close();
00105         pthread_mutex_unlock(&mutex);
00106         return NULL;
00107         }
00108         
00109 /*
00110  * This function is the routine for threadThree. It writes "three" in the text file. 
00111  * A mutex is used to avoid race condition amongst the threads  
00112  */
00113 void *TestFunction3L(void*)
00114         {
00115         // Start a file server session
00116         RFs aFs;
00117         User::LeaveIfError(aFs.Connect());
00118         
00119         RFile file;
00120         pthread_mutex_lock(&mutex);
00121         TInt pos = 0;
00122         for(int i=0; i<5;i++ )
00123                 {
00124                         //Push the file object on the cleanup stack before doing any file operation which could leave. 
00125                         CleanupClosePushL(file); 
00126                         file.Open(aFs,KTestFile,EFileRead|EFileWrite);
00127                         
00128                         _LIT8(KWriteBuf,"Three ,\n");
00129                         file.Seek(ESeekEnd , pos );
00130                         file.Write(pos ,KWriteBuf);
00131                         CleanupStack::PopAndDestroy(&file);
00132                         file.Close();
00133                         User::After(1000000); //Wait for 0.1 s to ensure a visible interthreading mechanism 
00134                 }
00135         aFs.Close();
00136         pthread_mutex_unlock(&mutex);
00137         return NULL;
00138         }
00139         
00140 /*
00141 * The following function creates three threads which starts executing as soon as it is created
00142 * it creates a text file which is used as a shared resource . The main thread will wait till 
00143 * child threads completes its execution . 
00144 */
00145 int CreateThreadL()
00146         {       
00147         //Three threads declared.
00148         pthread_t threadOne;
00149         pthread_t threadTwo;
00150         pthread_t threadThree;
00151         
00152         _LIT(KMain ,"in main\n" ); 
00153         console->Write(KMain);
00154         //Start a file server session 
00155         RFs aFs;        
00156         User::LeaveIfError(aFs.Connect());
00157         
00158         //Create a text file which can be used as a shared resource. 
00159         RFile file;
00160         CleanupClosePushL(file); 
00161         file.Create(aFs ,KTestFile,EFileRead|EFileWrite);
00162         CleanupStack::PopAndDestroy(&file);
00163         file.Close(); 
00164         aFs.Close();
00165         //Create and initialize mutex for synchronization       
00166         if((pthread_mutex_init(&mutex,NULL)) != 0)
00167                 {
00168                         return -1;
00169                 }         
00170         
00171         //Create threadOne.. thread is in running state. 
00172         TInt err1 = pthread_create(&threadOne,NULL,TestFunction1L, NULL);
00173         User::LeaveIfError(err1);
00174         _LIT(KThreadOneCreated , "ThreadOne created\n");
00175         console->Write(KThreadOneCreated);
00176         
00177         //Create threadTwo.. thread is in running state.
00178         TInt err2 = pthread_create(&threadTwo,NULL,TestFunction2L, NULL);
00179         User::LeaveIfError(err2);
00180         _LIT(KThreadTwoCreated , "ThreadTwo created\n");
00181         console->Write(KThreadTwoCreated);
00182         
00183         //Create threadThree.. thread is in running state.
00184         TInt err3 = pthread_create(&threadThree,NULL,TestFunction3L, NULL);
00185         User::LeaveIfError(err3);
00186         _LIT(KThreadThreeCreated , "ThreadThree created\n");
00187         console->Write(KThreadThreeCreated);
00188         
00189         
00190         //------Main thread waits for other threads to complete ---- 
00191         _LIT(KWait , "Waiting for child threads to complete execution\n");
00192         console->Write(KWait);
00193         
00194         _LIT(KJoinError , "Error in pthread_join()");
00195         //Main thread waits for threadOne to complete execution
00196         if(pthread_join(threadOne, NULL) != 0)
00197                 {
00198                         console->Write(KJoinError);      
00199                 }
00200         else
00201                 {
00202                         _LIT(KRetThreadOne ,"Returned from threadone\n"); 
00203                         console->Write(KRetThreadOne); //Control comes to main thread once threadOne completes execution.
00204                 }
00205 
00206         //Main thread waits for threadTwo to complete execution
00207         if(pthread_join(threadTwo, NULL) != 0)
00208                 {
00209                         console->Write(KJoinError);
00210                 }
00211         else
00212                 {
00213                         _LIT(KRetThreadTwo ,"Returned from threadtwo\n"); 
00214                         console->Write(KRetThreadTwo); //Control comes to main thread once threadTwo completes execution.
00215                 }
00216                 
00217         //Main thread waits for threadThree to complete execution
00218         if(pthread_join(threadThree, NULL) != 0)
00219                 {
00220                         console->Write(KJoinError);      
00221                 }
00222         else 
00223                 {
00224                         _LIT(KRetThreadThree ,"Returned from threadthree\n"); 
00225                         console->Write(KRetThreadThree); //Control comes to main thread once threadTwo completes execution.
00226                 }
00227         //Clean up
00228         pthread_mutex_destroy(&mutex);
00229         return -1; 
00230         }
00231         
00232         //  Local Functions
00233 
00234 LOCAL_C void MainL()
00235         {
00236         _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");
00237         console->Write(KHello);
00238         CreateThreadL();
00239         }
00240 
00241 LOCAL_C void DoStartL()
00242         {
00243         MainL();
00244         }
00245 
00246         //  Global Functions
00247 
00248 GLDEF_C TInt E32Main()
00249         {
00250         // Create cleanup stack
00251         __UHEAP_MARK;
00252         CTrapCleanup* cleanup = CTrapCleanup::New();
00253                 // Create output console
00254         _LIT(KTextConsoleTitle, "Console");
00255         TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen)));
00256         if (createError)
00257         return createError;
00258                 // Run application code inside TRAP harness, wait keypress when terminated
00259         TRAPD(mainError, DoStartL());
00260         _LIT(KTextFailed, " failed, leave code = %d");
00261         if (mainError)
00262         console->Printf(KTextFailed, mainError);
00263         _LIT(KTextPressAnyKey, " [press any key]\n");
00264         console->Printf(KTextPressAnyKey);
00265         console->Getch();
00266         delete console;
00267         delete cleanup;
00268         __UHEAP_MARKEND;
00269         return KErrNone;
00270         }
00271         

Generated by  doxygen 1.6.2