diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_smp_example_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_smp_example_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,407 @@ + + +TB10.1 Example Applications: examples/Base/SmpExample/src/SmpExample.cpp Source File + + + + +

examples/Base/SmpExample/src/SmpExample.cpp

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 
+00014 #include <d32dbms.h>  //Used for RDbDatabase class. 
+00015 #include "SmpExample.h"
+00016 _LIT(KDatabase1, "C:\\DBforSMP1.db");
+00017 _LIT(KDatabase2, "C:\\DBforSMP2.db");
+00018 
+00022 CSmpExample::~CSmpExample()
+00023     {
+00024     iReadThread.Close(); //Reader thread closed. 
+00025     iWriteThread1.Close(); //Writer thread closed. 
+00026     iWriteThread2.Close(); //Writer thread closed.
+00027     delete iConsole;
+00028     }
+00029 
+00033 CSmpExample* CSmpExample::NewL()
+00034     {
+00035     CSmpExample* self = new(ELeave)CSmpExample();
+00036     CleanupStack::PushL(self);
+00037     self->ConstructL();
+00038     CleanupStack::Pop(self);
+00039     return self;
+00040     }
+00041 
+00045 void CSmpExample::ConstructL()
+00046     { 
+00047     CreateDatabaseL(KDatabase1);
+00048     CreateDatabaseL(KDatabase2);
+00049     
+00050     _LIT(KTextConsoleTitle, "SmpExample");
+00051     iConsole = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen, KConsFullScreen));  
+00052 
+00053     //Creates a reader thread to read the databases.
+00054     _LIT(KReader, "ReaderThread");
+00055     User::LeaveIfError(iReadThread.Create(KReader, ReadThreadFuncL, KDefaultStackSize, KMinHeapSize, 256*KMinHeapSize, this, EOwnerProcess));   
+00056 
+00057     //Creates a writer thread to write to the DBforSMP1.db database. 
+00058     _LIT(KWriter1, "WriterThread1");
+00059     User::LeaveIfError(iWriteThread1.Create(KWriter1, WriteThread1FuncL, KDefaultStackSize, KMinHeapSize, 256*KMinHeapSize, this, EOwnerProcess));    
+00060     
+00061     //Creates a writer thread to write to the DBforSMP2.db database. 
+00062     _LIT(KWriter2, "WriterThread2");
+00063     User::LeaveIfError(iWriteThread2.Create(KWriter2, WriteThread2FuncL, KDefaultStackSize, KMinHeapSize, 256*KMinHeapSize, this, EOwnerProcess));           
+00064 
+00065 
+00066     //Sets priority to the threads. 
+00067     iWriteThread1.SetPriority(EPriorityMuchLess);
+00068     iWriteThread2.SetPriority(EPriorityMore);
+00069     iReadThread.SetPriority(EPriorityNormal);
+00070     }
+00071 
+00075 void CSmpExample::StartThreads()
+00076     {   
+00077     TRequestStatus writerThread1Status; 
+00078     TRequestStatus readerThreadStatus; 
+00079     TRequestStatus writerThread2Status; 
+00080     
+00081     _LIT(KTextPressKey, "\nPress any key to start writing to and reading from the database\n");
+00082     iConsole->Printf(KTextPressKey);
+00083     iConsole->Getch();
+00084   
+00085     //Requests a notification for the ReaderThread to terminate. 
+00086     iReadThread.Logon(readerThreadStatus);
+00087     iReadThread.Resume();
+00088     
+00089     //Requests a notification for the WriterThread1 to terminate. 
+00090     iWriteThread1.Logon(writerThread1Status);   
+00091     iWriteThread1.Resume();
+00092     
+00093     //Requests a notification for the WriterThread2 to terminate. 
+00094     iWriteThread2.Logon(writerThread2Status);   
+00095     iWriteThread2.Resume();
+00096     
+00097     //Control returns to the main thread when the all the threads terminate. 
+00098     User::WaitForRequest(writerThread1Status);
+00099     User::WaitForRequest(readerThreadStatus);
+00100     User::WaitForRequest(writerThread2Status);
+00101     }
+00102 
+00106 void CSmpExample::PrintMessage()
+00107     {
+00108     _LIT(KTextWelcome, "Welcome to the SmpExample.\n");
+00109     _LIT(KTextPurposel1, "There are three threads running in the example: WriterThread1 has the lowest priority,\n");
+00110     _LIT(KTextPurposel2, "ReaderThread has normal priority and WriterThread2 has maximum priority.\n");  
+00111     _LIT(KTextPurposel3, "The two WriterThreads open two different databases and write some integers to them.\n");
+00112     _LIT(KTextPurposel4, "ReaderThread reads the two databases and prints the output to the console.\n");
+00113     
+00114     _LIT(KTextPurposel5, "In a unicore environment, WriterThread1 will be scheduled to run last and would not have\n");
+00115     _LIT(KTextPurposel6, "written to the database when ReaderThread starts reading the databases.\n");
+00116     _LIT(KTextPurposel7, "But in an SMP environment, both the WriterThreads write to their respective databases simultaneously.\n");
+00117     
+00118     iConsole->Printf(KTextWelcome);
+00119     iConsole->Printf(KTextPurposel1);
+00120     iConsole->Printf(KTextPurposel2);
+00121     iConsole->Printf(KTextPurposel3);
+00122     iConsole->Printf(KTextPurposel4);
+00123     iConsole->Printf(KTextPurposel5);
+00124     iConsole->Printf(KTextPurposel6);
+00125     iConsole->Printf(KTextPurposel7);
+00126     }
+00127 
+00131 void CSmpExample::ReadDatabaseL(const TDesC& aDbName, CConsoleBase& console)
+00132     { 
+00133     //Creates a file server session object before any file system manipulation. 
+00134     RFs fsSession;
+00135     CleanupClosePushL(fsSession);
+00136     fsSession.Connect();
+00137     
+00138     //Creates Rdbs object
+00139     RDbs dbs;
+00140     CleanupClosePushL(dbs); 
+00141     dbs.Connect();
+00142     
+00143     //Opens the named database using the RDbs object
+00144     RDbNamedDatabase database;
+00145     CleanupClosePushL(database);
+00146     User::LeaveIfError(database.Open(dbs, aDbName)); 
+00147     
+00148     //Locks the database.
+00149     database.Begin();
+00150     //Prepare an SQL query to read one row of numbers from the database. 
+00151     _LIT(KSQLStatement, "Select Number1, Number2, Number3  from Numbers order by Number1, Number2, Number3");
+00152     
+00153     //Creates a view on the database to read it.
+00154     RDbView view; 
+00155     CleanupClosePushL(view);
+00156     
+00157     User::LeaveIfError(view.Prepare(database, TDbQuery(KSQLStatement, EDbCompareNormal)));
+00158     User::LeaveIfError(view.EvaluateAll());
+00159     
+00160     _LIT(KTextReading, "Reading the database\t %S.\n");
+00161     console.Printf(KTextReading, &aDbName);
+00162     
+00163     //Boolean variable to check whether the database is empty.
+00164     TBool isDbEmpty= EFalse;
+00165     //Iterates through the database till the last row is read. 
+00166     for (view.FirstL(); view.AtRow(); view.NextL())
+00167         {       
+00168         view.GetL();
+00169         TInt number1 = view.ColInt(1);
+00170         TInt number2 = view.ColInt(2);
+00171         TInt number3 = view.ColInt(3);
+00172         //Prepare a row formatter to print numbers in the console. 
+00173         _LIT(KRowFormatter, "Reading  %d \t%d\t%d\n");  
+00174         //Reads the integers from the view and display them in the console.
+00175         console.Printf(KRowFormatter, number1, number2, number3);
+00176         isDbEmpty= ETrue;
+00177         }
+00178     
+00179     if(isDbEmpty== EFalse)
+00180         {
+00181         _LIT(KTextDbEmpty, "Database is empty.\n\n");
+00182         console.Printf(KTextDbEmpty);
+00183         }
+00184     else
+00185         {
+00186         _LIT(KTextAllRead, "All the numbers in the database have been read.\n\n");
+00187         console.Printf(KTextAllRead);
+00188         }            
+00189     
+00190     CleanupStack::PopAndDestroy(&view); 
+00191     CleanupStack::PopAndDestroy(&database);  
+00192     CleanupStack::PopAndDestroy(&dbs);    
+00193     CleanupStack::PopAndDestroy(&fsSession);
+00194     }
+00195 
+00199 void CSmpExample::ReadBothDatabasesL()
+00200     {
+00201     _LIT(KTextConsoleTitle, "ReaderThread");
+00202     CConsoleBase* console= Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen, KConsFullScreen)); 
+00203     CleanupStack::PushL(console);
+00204 
+00205     //Reads DBforSMP1.db and prints the output to the console. 
+00206     ReadDatabaseL(KDatabase1, *console);
+00207     //Reads DBforSMP2.db and prints the output to the console.
+00208     ReadDatabaseL(KDatabase2, *console);
+00209     
+00210     _LIT(KExit, "Press any key to exit\n");
+00211     console->Printf(KExit);
+00212     console->Getch();
+00213     CleanupStack::PopAndDestroy(console);    
+00214     }
+00215 
+00220 TInt CSmpExample::ReadThreadFuncL(TAny* /*aPtr*/)
+00221     {
+00222     __UHEAP_MARK;
+00223     //Creates cleanup stack.
+00224     CTrapCleanup* cleanup = CTrapCleanup::New();
+00225     if(!cleanup)
+00226         {
+00227         return KErrNoMemory;
+00228         }
+00229      
+00230     TRAPD(error, ReadBothDatabasesL()); 
+00231     if(error != KErrNone)
+00232         {
+00233         _LIT(KUserPanic, "DB Read Failed");  
+00234         User::Panic(KUserPanic, error);
+00235         }
+00236     delete cleanup;
+00237     __UHEAP_MARKEND;
+00238     return KErrNone;
+00239     }
+00240 
+00245 void CSmpExample::WriteDbFuncL(const TDesC& aDbName, TInt aNum)
+00246     {
+00247     //Creates a file server session object before any file system manipulation. 
+00248     RFs fsSession;
+00249     CleanupClosePushL(fsSession);
+00250     fsSession.Connect();
+00251 
+00252 
+00253     //Creates Rdbs object   
+00254     RDbs dbs;
+00255     CleanupClosePushL(dbs);
+00256     dbs.Connect();
+00257     
+00258     //Opens the database using the RDbs object
+00259     RDbNamedDatabase database;
+00260     CleanupClosePushL(database);
+00261     User::LeaveIfError(database.Open(dbs, aDbName)); 
+00262     
+00263     //Locks the database.
+00264     database.Begin();
+00265     
+00266     //Creates a view on the database. 
+00267     RDbView view;
+00268     CleanupClosePushL(view);
+00269     _LIT(KSQLStatement, "Select Number1, Number2, Number3 from Numbers order by Number1, Number2, Number3");
+00270     User::LeaveIfError(view.Prepare(database, TDbQuery(KSQLStatement, EDbCompareNormal)));
+00271     User::LeaveIfError(view.EvaluateAll());
+00272 
+00273     for(int i=0; i<5; i++)
+00274         {
+00275         //Inserts a new row at the end of the database. 
+00276         view.InsertL();
+00277         //Fills three columns with numbers.
+00278         view.SetColL(1, aNum++);
+00279         view.SetColL(2, aNum++);
+00280         view.SetColL(3, aNum++);
+00281         view.PutL();
+00282         }
+00283 
+00284     CleanupStack::PopAndDestroy(&view);       
+00285     //Commits the database and unlocks it. 
+00286     database.Commit();
+00287     CleanupStack::PopAndDestroy(&database);  
+00288     CleanupStack::PopAndDestroy(&dbs);   
+00289     CleanupStack::PopAndDestroy(&fsSession);
+00290     }
+00291 
+00292 
+00297 TInt CSmpExample::WriteThread2FuncL(TAny* /*aPtr*/)
+00298     {
+00299     __UHEAP_MARK;
+00300     //Creates cleanup stack.
+00301     CTrapCleanup* cleanup = CTrapCleanup::New();
+00302     if(!cleanup)
+00303         {
+00304         return KErrNoMemory;
+00305         }
+00306     
+00307     //First number to be written to the database. 
+00308     const int KFirstNumforDb2 = 500; 
+00309     TRAPD(err, WriteDbFuncL(KDatabase2, KFirstNumforDb2));
+00310     if(err != KErrNone)
+00311         {
+00312         _LIT(KUserPanic, "DB Write Failed");  
+00313         User::Panic(KUserPanic, err);
+00314         }
+00315     delete cleanup;
+00316     __UHEAP_MARKEND;
+00317     return KErrNone;
+00318     }
+00319 
+00324 TInt CSmpExample::WriteThread1FuncL(TAny* /*aPtr*/)
+00325     {
+00326     __UHEAP_MARK;
+00327     //Creates cleanup stack.
+00328     CTrapCleanup* cleanup = CTrapCleanup::New();
+00329     if(!cleanup)
+00330         {
+00331         return KErrNoMemory;
+00332         }
+00333 
+00334     //First number to be written to the database. 
+00335     const int KFirstNumforDb1 = 0; 
+00336     TRAPD(err, WriteDbFuncL(KDatabase1, KFirstNumforDb1));
+00337     if(err != KErrNone)
+00338         {
+00339         _LIT(KUserPanic, "DB Write Failed");  
+00340         User::Panic(KUserPanic, err);
+00341         }
+00342     delete cleanup;
+00343     __UHEAP_MARKEND;
+00344     return KErrNone;
+00345     }
+00346 
+00351 void CSmpExample::CreateDatabaseL(const TDesC& aDbName)
+00352     {
+00353     //Creates a file server session object before any file system manipulation. 
+00354     RFs fsSession;
+00355     CleanupClosePushL(fsSession);
+00356     fsSession.Connect();
+00357 
+00358     //Creates Rdbs object
+00359     RDbs dbs;
+00360     CleanupClosePushL(dbs); 
+00361     dbs.Connect();
+00362     
+00363     //Creates a new database with the name specified in the parameter aDbName, 
+00364     //if database with same name is present, it will be replaced.    
+00365     RDbNamedDatabase database;
+00366     CleanupClosePushL(database);  
+00367     User::LeaveIfError(database.Replace(fsSession, aDbName)); 
+00368     database.Close(); 
+00369     
+00370     //Opens the database using the RDbs object
+00371     User::LeaveIfError(database.Open(dbs, aDbName));       
+00372     //Creates a table definition.
+00373     CDbColSet* columns=CDbColSet::NewLC();
+00374 
+00375     //Adds three columns each containing Int32 values. 
+00376     _LIT(KCol1, "Number1");
+00377     _LIT(KCol2, "Number2");
+00378     _LIT(KCol3, "Number3");   
+00379     columns->AddL(TDbCol(KCol1, EDbColInt32));
+00380     columns->AddL(TDbCol(KCol2, EDbColInt32));
+00381     columns->AddL(TDbCol(KCol3, EDbColInt32));
+00382  
+00383 
+00384      //Creates the table, table name is "Numbers" and add the columns to it.
+00385     _LIT(KTable, "Numbers");
+00386     User::LeaveIfError(database.CreateTable(KTable, *columns));
+00387     
+00388     CDbKey* key=CDbKey::NewLC();
+00389 
+00390      //Add the key columns.
+00391      TDbKeyCol number1(KCol1);
+00392      key->AddL(number1);
+00393      TDbKeyCol number2(KCol2);
+00394      key->AddL(number2);
+00395      TDbKeyCol number3(KCol3);
+00396      key->AddL(number3);
+00397     User::LeaveIfError(database.CreateIndex(KTable, KTable, *key));
+00398     
+00399     //Cleans up the column set.  
+00400     CleanupStack::PopAndDestroy(key);
+00401     CleanupStack::PopAndDestroy(columns);  
+00402     CleanupStack::PopAndDestroy(&database);  
+00403     CleanupStack::PopAndDestroy(&dbs);   
+00404     CleanupStack::PopAndDestroy(&fsSession);
+00405     }
+00406 
+00411 static void MainL()
+00412     {
+00413     CSmpExample* smpExample = CSmpExample::NewL();
+00414     CleanupStack::PushL(smpExample);    
+00415     smpExample->PrintMessage();
+00416     smpExample->StartThreads();
+00417     CleanupStack::PopAndDestroy(smpExample);
+00418     }
+00419 
+00423 extern TInt E32Main()
+00424     {
+00425     //Creates cleanup stack.
+00426     __UHEAP_MARK;
+00427     CTrapCleanup* cleanup = CTrapCleanup::New();
+00428     if(!cleanup)
+00429         {
+00430         return KErrNoMemory;
+00431         }
+00432     //Run application code inside a TRAP harness.
+00433     TRAPD(mainError, MainL());
+00434     if(mainError != KErrNone)
+00435         {
+00436         _LIT(KUserPanic, "Main Failed");  
+00437         User::Panic(KUserPanic, mainError);
+00438         }
+00439     delete cleanup;
+00440     __UHEAP_MARKEND;
+00441     return KErrNone;
+00442     }
+00443 
+

Generated on Thu Jan 21 10:32:57 2010 for TB10.1 Example Applications by  + +doxygen 1.5.3
+ +