00001 // -*- c++ -*- 00002 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 00003 00004 // O S C L _ E R R O R _ T R A P C L E A N U P 00005 00006 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 00007 00018 #ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED 00019 #define OSCL_ERROR_TRAPCLEANUP_H_INCLUDED 00020 00021 #ifndef OSCLCONFIG_ERROR_H_INCLUDED 00022 #include "osclconfig_error.h" 00023 #endif 00024 00025 00026 00027 #ifndef OSCL_HEAPBASE_H_INCLUDED 00028 #include "oscl_heapbase.h" 00029 #endif 00030 00031 #define OSCL_MAX_TRAP_LEVELS 20 00032 00036 class OsclTrapStackItem 00037 { 00038 public: 00039 OsclTrapStackItem() {} 00040 OsclTrapStackItem(_OsclHeapBase *aCBase) 00041 { 00042 iCBase = aCBase; 00043 iTAny = (OsclAny*)aCBase; 00044 iTrapOperation = NULL; 00045 iNext = NULL; 00046 } 00047 OsclTrapStackItem(OsclAny *aTAny) 00048 { 00049 iCBase = NULL; 00050 iTAny = aTAny; 00051 iTrapOperation = NULL; 00052 iNext = NULL; 00053 } 00054 OsclTrapStackItem(OsclTrapItem aItem) 00055 { 00056 iCBase = NULL; 00057 iTAny = aItem.iPtr; 00058 iTrapOperation = aItem.iOperation; 00059 iNext = NULL; 00060 } 00061 _OsclHeapBase *iCBase; 00062 OsclAny *iTAny; 00063 OsclTrapOperation iTrapOperation; 00064 OsclTrapStackItem *iNext; 00065 }; 00066 00067 class OsclJump; 00068 00069 #ifndef OSCL_ERROR_IMP_H_INCLUDED 00070 #include "oscl_error_imp.h" 00071 #endif 00072 00073 #ifndef OSCL_DEFALLOC_H_INCLUDED 00074 #include "oscl_defalloc.h" 00075 #endif 00076 00077 #ifndef OSCL_ASSERT_H_INCLUDED 00078 #include "oscl_assert.h" 00079 #endif 00080 00081 #ifndef OSCL_ERROR_H_INCLUDED 00082 #include "oscl_error.h" 00083 #endif 00084 00089 class OsclTrapStack 00090 { 00091 private: 00092 OsclTrapStack(Oscl_DefAlloc *iAlloc); 00093 ~OsclTrapStack(); 00094 00095 //Trap APIs 00096 inline void Trap(); 00097 inline bool UnTrap(); 00098 00099 //Cleanup stack APIs 00100 void PushL(_OsclHeapBase *aCBase); 00101 void PushL(OsclAny *aTAny); 00102 void PushL(OsclTrapItem anItem); 00103 void Push(OsclTrapStackItem *aItem); 00104 void Pop(); 00105 void Pop(int32 aCount); 00106 void PopDealloc(); 00107 void PopDealloc(int32 aCount); 00108 void Leaving(); 00109 00110 //top of cleanup stack 00111 OsclTrapStackItem *iTop; 00112 00113 //cleanup stack allocator. 00114 Oscl_DefAlloc *iAlloc; 00115 00116 friend class OsclError; 00117 friend class OsclErrorTrap; 00118 friend class OsclErrorTrapImp; 00119 00120 private: 00121 //The trap mark stack is a stack used to mark the top of the cleanup stack 00122 //for each trap level. 00123 00124 inline void PushTrapL(OsclAny *aTAny); 00125 inline void PopTrap(); 00126 00127 //top of trap mark stack 00128 OsclTrapStackItem *TrapTop() 00129 { 00130 if (iTrapTopIndex >= 0) 00131 return &iTrapTopArray[iTrapTopIndex]; 00132 return NULL; 00133 } 00134 00135 OsclTrapStackItem iTrapTopArray[OSCL_MAX_TRAP_LEVELS]; 00136 00137 //index to top of stack, or (-1) when stack is empty 00138 int32 iTrapTopIndex; 00139 00140 void pushTrapIndex() 00141 { 00142 OSCL_ASSERT(iTrapTopIndex < (OSCL_MAX_TRAP_LEVELS - 1));//stack overflow 00143 iTrapTopIndex++; 00144 } 00145 00146 void popTrapIndex() 00147 { 00148 OSCL_ASSERT(iTrapTopIndex >= 0);//stack underflow 00149 iTrapTopIndex--; 00150 } 00151 }; 00152 00153 00154 00155 #ifndef OSCL_BASE_ALLOC_H_INCLUDED 00156 #include "oscl_base_alloc.h" 00157 #endif 00158 00159 //For non-symbian, the error trap stack must be in a global registry. 00160 // 00161 //Use TLS registry unless it's not available, then 00162 //use singleton. 00163 //Note: singleton-based registry only works for single-threaded 00164 //scenarios because this implementation assumes a per-thread registry. 00165 #include "oscl_tls.h" 00166 #include "oscl_singleton.h" 00167 #define PVERRORTRAP_REGISTRY_ID OSCL_TLS_ID_PVERRORTRAP 00168 #define PVERRORTRAP_REGISTRY OsclTLSRegistry 00169 00170 00174 class OsclErrorTrapImp 00175 { 00176 public: 00181 OSCL_IMPORT_REF void UnTrap(); 00182 #if defined(PVERROR_IMP_JUMPS) 00183 OsclJump *iJumpData; 00184 #endif 00185 00186 //Global leave info. 00187 int32 iLeave; 00188 00189 public: 00193 OSCL_IMPORT_REF static OsclErrorTrapImp* Trap(); 00194 //This version of Trap is identical to the above, except it avoids the TLS lookup. 00195 OSCL_IMPORT_REF static OsclErrorTrapImp* TrapNoTls(OsclErrorTrapImp*); 00196 OsclTrapStack *iTrapStack; 00197 00198 private: 00199 OsclErrorTrapImp(Oscl_DefAlloc *aAlloc, int32 &error); 00200 ~OsclErrorTrapImp(); 00201 Oscl_DefAlloc *iAlloc; 00202 00203 static OsclErrorTrapImp* GetErrorTrap(int32& aError) 00204 //static function to get currently installed error trap 00205 //for this thread. 00206 { 00207 OsclErrorTrapImp *current = (OsclErrorTrapImp*)PVERRORTRAP_REGISTRY::getInstance(PVERRORTRAP_REGISTRY_ID, aError); 00208 return current; 00209 } 00210 static OsclErrorTrapImp* GetErrorTrap() 00211 //static function to get currently installed error trap 00212 //for this thread. returns NULL on error. 00213 { 00214 int32 error; 00215 OsclErrorTrapImp* current = GetErrorTrap(error); 00216 if (error) 00217 return NULL; 00218 return current; 00219 } 00220 00221 static OsclErrorTrapImp* SetErrorTrap(OsclErrorTrapImp* a, int32& aError) 00222 //static function to set currently installed error trap 00223 //for this thread. return previous error trap, if any. 00224 { 00225 OsclErrorTrapImp* temp = GetErrorTrap(aError); 00226 PVERRORTRAP_REGISTRY::registerInstance(a, PVERRORTRAP_REGISTRY_ID, aError); 00227 return temp; 00228 } 00229 00230 //Global cleanup function for OsclAny items. 00231 static void TrapOperation(OsclAny *ptr) 00232 { 00233 int32 error; 00234 OsclErrorTrapImp *trap = GetErrorTrap(error); 00235 if (trap && trap->iAlloc) 00236 trap->iAlloc->deallocate(ptr); 00237 else 00238 { 00239 _OsclBasicAllocator alloc; 00240 alloc.deallocate(ptr); 00241 } 00242 } 00243 00244 //default allocators. 00245 _OsclBasicAllocator iDefAlloc; 00246 00247 friend class OsclErrorTrap; 00248 friend class OsclError; 00249 friend class OsclExecScheduler; 00250 friend class OsclExecSchedulerCommonBase; 00251 friend class OsclJump; 00252 friend class OsclJumpMark; 00253 friend class OsclTrapStack; 00254 friend class CPVInterfaceProxy; 00255 friend class OsclScheduler; 00256 }; 00257 00258 00259 #endif 00260