examples/Base/MemMan/Cleanup/TwoPhaseOOM/TwoPhaseOOM.cpp

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

Generated by  doxygen 1.6.2