examples/Base/MemMan/Cleanup/TwoPhaseOOM/TwoPhaseOOM.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 NOTE: the structure of this example is different to standard E32 examples 
00029 */
00030 
00031 
00032 
00033 #include <e32cons.h>
00034 
00035   // All messages written to this
00036 LOCAL_D CConsoleBase* console;
00037   
00038   // Function prototypes
00039 LOCAL_C void doExampleL();      
00040 LOCAL_C void callExampleL();
00041 
00042 
00044 //
00045 // -----> CSimple (definition)
00046 //
00048 class CSimple : public CBase
00049         {
00050 public :
00051         static CSimple* NewL(TInt aVal);
00052         static CSimple* NewLC(TInt aVal);
00053         void   Display();
00054 protected: 
00055         CSimple(TInt aVal);
00056 public: 
00057         TInt   iVal;
00058         };
00059 
00060 
00062 //
00063 // -----> CCompound (definition)
00064 //
00066 class CCompound : public CBase
00067         {
00068 public :
00069         virtual  ~CCompound();
00070         void     Display();
00071         static   CCompound* NewL(TInt aRoot,TInt aChild);
00072         static   CCompound* NewLC(TInt aRoot,TInt aChild);
00073 private:
00074         void     ConstructL(TInt aRoot,TInt aChild);
00075 private:
00076         TInt     iRoot;
00077         CSimple* iChild;
00078     };
00079 
00081 //
00082 // -----> CCompound (implementation)
00083 //
00085 
00086                                 // Use two stage construction technique to 
00087                                 // prevent alloc heaven.
00088                                 // NB. due to use of cleanup stack, NewLC is
00089                                 // now the primitive, rather than NewL
00090 
00091                                 // NewLC with two stage construct
00092 CCompound* CCompound::NewLC(TInt aRoot,TInt aChild) 
00093                 {               // get new, leave if can't      
00094                 CCompound* self=new (ELeave) CCompound;
00095                 CleanupStack::PushL(self);
00096                                 // push onto cleanup stack (in 
00097                                 // case self->ConstructL leaves).
00098                                 // Use two-stage construct
00099                 self->ConstructL(aRoot,aChild);
00100                 return self;
00101                 }
00102                                 // version of NewLC which leaves 
00103                                 // nothing on the cleanup stack
00104 CCompound* CCompound::NewL(TInt aRoot,TInt aChild) 
00105                 {
00106                 CCompound* self=NewLC(aRoot,aChild);
00107                 CleanupStack::Pop();
00108                 return self;
00109                 }
00110                                 // NB. function may leave, 
00111                                 // as CSimple::NewL may leave
00112 void CCompound::ConstructL(TInt aRoot,TInt aChild) 
00113                 {
00114                 iRoot = aRoot;
00115                 iChild = CSimple::NewL(aChild);  
00116                 iChild->iVal = aChild;
00117                 }                               
00118 
00119 void CCompound::Display() 
00120         {
00121           // Display class member data on the console
00122         _LIT(KFormat4,"Root=%d. Child=%d.\n");
00123     console->Printf(KFormat4,iRoot,iChild->iVal);
00124         }
00125                                 
00126 CCompound::~CCompound() 
00127         {
00128         _LIT(KMsgDestCCompound,"Destructing CCompound\n");
00129         console->Printf(KMsgDestCCompound);
00130         delete iChild;
00131         }
00132 
00133 
00135 //
00136 // -----> CSimple (implementation)
00137 //
00139 CSimple* CSimple::NewL(TInt aVal) 
00140         {
00141           // NB The NewL function uses the C++ constructor mechanism.
00142         CSimple* self=new (ELeave) CSimple(aVal);
00143         return self;
00144         }
00145 
00146                                 
00147 CSimple* CSimple::NewLC(TInt aVal)
00148         {
00149           // NewLC is enriched with a push to the cleanup stack
00150         CSimple* self=NewL(aVal);       
00151         CleanupStack::PushL(self);
00152         return self;
00153         }
00154 
00155                                 
00156 void CSimple::Display() 
00157         {
00158           // Display class data member on the console.
00159         _LIT(KFormat1,"Value=%d.\n");
00160         console->Printf(KFormat1,iVal);
00161         }
00162  
00163 CSimple::CSimple(TInt aVal) 
00164         : iVal(aVal)
00165         {}
00166 
00167 
00169 //
00170 // Main function called by E32
00171 //
00173 GLDEF_C TInt E32Main()
00174     {
00175           // Get cleanup stack
00176         CTrapCleanup* cleanup=CTrapCleanup::New();
00177 
00178           // Some more initialization, then do the example
00179         TRAPD(error,callExampleL());
00180           
00181           // callExampleL() should never leave.
00182         _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
00183         __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));
00184 
00185           // destroy the cleanup stack
00186         delete cleanup;
00187         
00188           // return
00189         return 0;
00190     }
00191 
00192 
00194 //
00195 //
00196 //
00198 LOCAL_C void callExampleL() 
00199     {
00200           // Initialize and call the example code under cleanup stack.
00201         _LIT(KMsgExampleCode,"Symbian platform Example Code");
00202         console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00203           // Put console onto the cleanup stack.
00204         CleanupStack::PushL(console);
00205 
00206           // Mark for alloc heaven tool
00207         __UHEAP_MARK;                      
00208 
00209           // Perform the example function under the protection of a 
00210           // TRAP harness.
00211         TRAPD(error,doExampleL());
00212         
00213           // Test the example for alloc heaven
00214           __UHEAP_MARKEND;
00215 
00216           // 
00217         _LIT(KMsgOK,"ok");
00218         _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
00219         if (error)
00220                 console->Printf(KFormat2, error);
00221         else
00222                 console->Printf(KMsgOK);
00223           
00224           // Continue
00225         _LIT(KMsgPressAnyKey," [press any key]");
00226         console->Printf(KMsgPressAnyKey);
00227         console->Getch();
00228 
00229           // Remove the console object from the cleanupstack
00230           // and destroy it. 
00231         CleanupStack::PopAndDestroy();
00232     }
00233 
00234 
00236 //
00237 // Do the example
00238 //
00239 // Example to check robustness of class on OOM and attempt to provoke
00240 // memory leaks (orphans).
00242 void doExampleL()
00243         {
00244         #if defined(_DEBUG)  //only ever used in debug mode
00245         TInt failValue = 5;
00246         #endif
00247 
00248           // Startup the alloc failure tool to fail in the third cycle.
00249           // To test for alloc heaven:
00250           //
00251           // An even value for 'failValue' should provoke memory leak,
00252           // an odd value should not.
00253         __UHEAP_SETFAIL(RHeap::EDeterministic,failValue);
00254         
00255         for(TInt ii=1;ii<4;ii++)
00256                 {
00257                   // Display status information
00258                 _LIT(KFormat3,"Cycle %d.\n");
00259                 console->Printf(KFormat3,ii);
00260                   // Create new instance 
00261                 CCompound* myCompoundExample = CCompound::NewL(1,2);
00262                   // Display the instance
00263                 myCompoundExample->Display();
00264                   // Destroy the instance
00265                 delete myCompoundExample;
00266                 } 
00267         }
00268 
00269 

Generated by  doxygen 1.6.2