examples/Base/IPC/Async/RealLifeWaitLoop/RealLifeWaitLoop.cpp

00001 /*
00002 Copyright (c) 2000-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: 
00028 Show asynchronous programming (without active objects)
00029 Example introduces the "complications" involved in real-life
00030 wait loops, which always deal with multiple asynchronous
00031 service providers 
00032 */
00033 
00034 
00035 
00036 
00037 
00038 #include "CommonFramework.h"
00039 #include <e32math.h>
00040 
00041 //
00042 // Common literal text
00043 //
00044 
00045 _LIT(KMsgQuickCancelled,"Quick service request canceled\n");
00046 
00047 //
00048 // utility functions
00049 //
00050 
00051 LOCAL_D TInt64 smallRandSeed;
00052 
00053 LOCAL_C TInt smallRand()
00054         {
00055           // produce small random numbers in range 0..9
00056         TInt bigResult=Math::Rand(smallRandSeed);// result uses full 32-bit range
00057         return bigResult % 10;                   // return result mod 10
00058         }
00059 
00060 LOCAL_C void sleep(TInt aTenths)
00061         {
00062           // sleep for an interval measured in tenths of a second
00063         User::After(aTenths*100000); // just let the User function do it for us
00064         }
00065 
00066 
00067 // Do the example
00068 LOCAL_C void doExampleL()
00069     {
00070           // create and initialize heartbeat timer
00071         RTimer heartbeat;               // Heartbeat timer.
00072         TRequestStatus heartbeatStatus; // Request status associated with it.
00073         heartbeat.CreateLocal();        // Always created for this thread.
00074 
00075           // create stuff for secondary timer
00076         RTimer quickService;                    // A quick service.
00077         TRequestStatus quickServiceStatus;      // Ccorresponding status.
00078         TBool quickServiceRequestIssued=EFalse; // Whether request issued.
00079         quickService.CreateLocal();             // Create timer.
00080 
00081           // issue first heartbeat request
00082         heartbeat.After(heartbeatStatus,1000000); // Request completion
00083                                                   // after 1 second.
00084         TInt heartbeatTick=0;                     // Ccounts heartbeat ticks.
00085 
00086           // wait loop
00087         for (;;)
00088                 {
00089                   // Wait for any request
00090                 User::WaitForAnyRequest();
00091                   // find out which request completed, and handle it
00092                 if (heartbeatStatus!=KRequestPending)
00093                         { 
00094                           // heartbeat completed so service request
00095                         _LIT(KMsgServicing,"Servicing heartbeat tick %d ...\n");
00096                         console->Printf(KMsgServicing,heartbeatTick);
00097                           // take some time over it
00098                         sleep(smallRand());
00099 
00100                         if (smallRand() < 5)
00101                                 { 
00102                                   // issue a quick request 50% of the time
00103                                   // cancel any outstanding quick request
00104                                 if (quickServiceRequestIssued)
00105                                         {
00106                                         quickService.Cancel();            // cancel request
00107                                         User::WaitForRequest(quickServiceStatus); // wait
00108                                         quickServiceRequestIssued=EFalse; // indicate not issued
00109                                         console->Printf(KMsgQuickCancelled);
00110                                         }
00111                                   // issue new quick request
00112                                 quickService.After(quickServiceStatus,(smallRand()*2)*100000);
00113                                   // request an event after 0 .. 1.8 seconds
00114                                 quickServiceRequestIssued=ETrue; // indicate request issued
00115                                 _LIT(KMsgQuickIssued,"Quick service request issued\n");
00116                                 console->Printf(KMsgQuickIssued);
00117                                 }
00118 
00119                         _LIT(KMsgServiced,"... heartbeat tick %d serviced\n");
00120                         console->Printf(KMsgServiced, heartbeatTick);
00121                           // test whether processing should finish
00122                         if (heartbeatTick >= 10)
00123                                 { 
00124                                   // 10 heart-beats: processing finished
00125                                 _LIT(KMsgFinishing,"Finishing\n");
00126                                 console->Printf(KMsgFinishing);
00127 
00128                                   // cancel quick request, if outstanding
00129                                 if (quickServiceRequestIssued)
00130                                         {
00131                                           // only relevant if request issued
00132                                         quickService.Cancel(); // request early completion
00133                                         User::WaitForRequest(quickServiceStatus); // wait
00134                                         quickServiceRequestIssued=EFalse;
00135                                           // request no longer issued
00136                                         console->Printf(KMsgQuickCancelled);
00137                                         }
00138 
00139                                 break; // finish wait loop
00140                                 }
00141                           // re-issue request
00142                         heartbeatTick++; // increment tick counter
00143                         heartbeat.After(heartbeatStatus,1000000); // another second
00144                         }
00145 
00146                 else if (quickServiceRequestIssued && quickServiceStatus!=KRequestPending)
00147                         { // if quick service request issued, and completed, then service it
00148                         _LIT(KMsgQuickCompleted,"Quick request completed\n");
00149                         console->Printf(KMsgQuickCompleted);
00150                         quickServiceRequestIssued=EFalse; // indicate request not issued
00151                         }
00152 
00153                 else
00154                         { // stray signal
00155                         _LIT(KMsgStraySignal,"Stray signal\n");
00156                         User::Panic(KMsgStraySignal, 1); // panic!
00157                         }
00158                 }
00159 
00160         // close quick service
00161         quickService.Close(); // close
00162 
00163         // close timer
00164         heartbeat.Close(); // close timer
00165         }

Generated by  doxygen 1.6.2