1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 // -*- c++ -*- 19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 20 21 // O S C L _ E R R O R 22 23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 24 25 /*! \addtogroup osclerror OSCL Error 26 * 27 * @{ 28 */ 29 30 31 /** \file oscl_error.h 32 \brief OSCL Error trap and cleanup include file 33 */ 34 35 #ifndef OSCL_ERROR_H_INCLUDED 36 #define OSCL_ERROR_H_INCLUDED 37 38 #ifndef OSCL_HEAPBASE_H_INCLUDED 39 #include "oscl_heapbase.h" 40 #endif 41 42 #ifndef OSCL_DEFALLOC_H_INCLUDED 43 #include "oscl_defalloc.h" 44 #endif 45 46 #ifndef OSCL_ERROR_CODES_H_INCLUDED 47 #include "oscl_error_codes.h" 48 #endif 49 50 /** 51 //Per-thread Error trap init. 52 */ 53 class OsclErrorTrapImp; 54 class OsclErrorTrap 55 { 56 public: 57 /** 58 * Allocate and initialize error trap for 59 * the calling thread. 60 * @param aAlloc: optional, allocator to use for 61 * the internal implementation. 62 * @return 0 for success, or an error 63 */ 64 OSCL_IMPORT_REF static int32 Init(Oscl_DefAlloc *aAlloc = NULL); 65 /** 66 * Cleanup and destroy error trap for 67 * the calling thread. 68 * @return 0 for success, or an error 69 */ 70 OSCL_IMPORT_REF static int32 Cleanup(); 71 /** 72 * Get the ErrorTrapImp for the current thread. 73 * Leaves on error. 74 */ 75 OSCL_IMPORT_REF static OsclErrorTrapImp* GetErrorTrapImp(); 76 }; 77 78 79 /** 80 //User Error class 81 */ 82 class OsclError 83 { 84 public: 85 /** 86 //Cleanup stack operations. 87 */ 88 89 /** Push an _OsclHeapBase item onto the cleanup stack. 90 */ 91 OSCL_IMPORT_REF static void PushL(_OsclHeapBase * aPtr); 92 93 /** Push an OsclAny item onto the cleanup stack. 94 */ 95 OSCL_IMPORT_REF static void PushL(OsclAny* aPtr); 96 97 /** Push an OsclTrapItem onto the cleanup stack 98 */ 99 OSCL_IMPORT_REF static void PushL(OsclTrapItem anItem); 100 101 /** Pop the cleanup stack 102 */ 103 OSCL_IMPORT_REF static void Pop(); 104 105 /** Pop the cleanup stack N times 106 */ 107 OSCL_IMPORT_REF static void Pop(int32 aCount); 108 109 /** Destroy the item on the top of the cleanup 110 * stack and pop it 111 */ 112 OSCL_IMPORT_REF static void PopDealloc(); 113 114 /** PopDealloc N times 115 */ 116 OSCL_IMPORT_REF static void PopDealloc(int32 aCount); 117 118 /** Do a Leave error, with the given reason code. 119 ** When a leave occurs, all items on the cleanup stack 120 ** for the current trap level will be destroyed, and 121 ** execution will jump to the trap handler. 122 */ 123 OSCL_IMPORT_REF static void Leave(int32 aReason); 124 125 /** Evaluate the input parameter, and if it is null, 126 ** do a Leave with OsclErrNoMemory reason code. 127 */ 128 OSCL_IMPORT_REF static void LeaveIfNull(OsclAny *a); 129 130 /** Evaluate the input parameter, and if it is an 131 ** error code (non-zero), then do a Leave with the 132 ** provided reason code. 133 */ 134 OSCL_IMPORT_REF static void LeaveIfError(int32 aReason); 135 136 }; 137 138 /** Cleanup Stack user macros 139 */ 140 #define OSCL_TRAPSTACK_PUSH(a) OsclError::PushL(a) 141 #define OSCL_TRAPSTACK_POP() OsclError::Pop() 142 #define OSCL_TRAPSTACK_POPDEALLOC() OsclError::PopDealloc() 143 144 /** 145 * TLS & Singleton registry calls that throw exceptions on errors. 146 */ 147 148 //Map TPVBaseErrorEnum return codes to Oscl Error leave codes 149 //Some of these codes indicate failure to init Oscl layer, in 150 //that case they map to zero and assert. 151 static const int32 _OsclBaseToErrorMap[] = 152 { 153 /*0*/OsclErrGeneral 154 ,/*EPVErrorBaseNotInstalled=1*/0 155 ,/*EPVErrorBaseAlreadyInstalled=2*/OsclErrAlreadyInstalled 156 ,/*EPVErrorBaseOutOfMemory=3*/OsclErrNoMemory 157 ,/*EPVErrorBaseSystemCallFailed=4*/OsclErrSystemCallFailed 158 ,/*EPVErrorBaseTooManyThreads=5*/0 159 ,/*EPVErrorBaseNotSupported=6*/OsclErrNotSupported 160 ,/*EPVErrorBaseNotReady=7*/OsclErrNotReady 161 }; 162 163 #include "oscl_singleton.h" 164 #include "oscl_assert.h" 165 #if(OSCL_HAS_SINGLETON_SUPPORT) 166 class OsclSingletonRegistryEx 167 { 168 public: 169 /* 170 ** Get an entry 171 ** @param ID: identifier 172 ** @returns: the entry value 173 ** @exception: leaves on error. 174 */ getInstance(uint32 ID)175 static OsclAny* getInstance(uint32 ID) 176 { 177 int32 error; 178 OsclAny* val = OsclSingletonRegistry::getInstance(ID, error); 179 if (error) 180 { 181 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 182 OsclError::Leave(_OsclBaseToErrorMap[error]); 183 } 184 return val; 185 } 186 187 /* 188 ** Set an entry 189 ** @param ID: identifier 190 ** @returns: the entry value 191 ** @exception: leaves on error. 192 */ registerInstance(OsclAny * ptr,uint32 ID)193 static void registerInstance(OsclAny* ptr, uint32 ID) 194 { 195 int32 error; 196 OsclSingletonRegistry::registerInstance(ptr, ID, error); 197 if (error) 198 { 199 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 200 OsclError::Leave(_OsclBaseToErrorMap[error]); 201 } 202 } 203 204 /* 205 //These two APIs can be used to do "test and set" operations on a singleton. 206 //Be sure to always call both APIs to avoid deadlock. 207 */ 208 209 /* 210 * Return the current value of the singleton and leave the singleton table locked 211 * on return. 212 * @param ID the singleton ID 213 * @returns the singleton value. 214 ** @exception: leaves on error. 215 */ lockAndGetInstance(uint32 ID)216 static OsclAny* lockAndGetInstance(uint32 ID) 217 { 218 int32 error; 219 OsclAny* val = OsclSingletonRegistry::lockAndGetInstance(ID, error); 220 if (error) 221 { 222 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 223 OsclError::Leave(_OsclBaseToErrorMap[error]); 224 } 225 return val; 226 } 227 228 /* 229 * Set the value of the singleton. Assume the singleton table is locked on entry. 230 * @param ptr the singleton value 231 * @param ID the singleton ID 232 ** @exception: leaves on error. 233 */ registerInstanceAndUnlock(OsclAny * ptr,uint32 ID)234 static void registerInstanceAndUnlock(OsclAny* ptr, uint32 ID) 235 { 236 int32 error; 237 OsclSingletonRegistry::registerInstanceAndUnlock(ptr, ID, error); 238 if (error) 239 { 240 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 241 OsclError::Leave(_OsclBaseToErrorMap[error]); 242 } 243 } 244 }; 245 246 template < class T, uint32 ID, class Registry = OsclSingletonRegistryEx > class OsclSingletonEx 247 { 248 private: 249 // make the copy constructor and assignment operator private 250 OsclSingletonEx& operator=(OsclSingletonEx& _Y) 251 { 252 return(*this); 253 } 254 255 protected: 256 T* _Ptr; 257 258 public: OsclSingletonEx()259 OsclSingletonEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {}; 260 ~OsclSingletonEx()261 ~OsclSingletonEx() {}; 262 263 /** 264 * @brief The indirection operator (*) accesses a value indirectly, 265 * through a pointer 266 * 267 * This operator ensures that the OsclSingleton can be used like the 268 * regular pointer that it was initialized with. 269 */ 270 T& operator*() const 271 { 272 return(*_Ptr); 273 } 274 275 /** 276 * @brief The indirection operator (->) accesses a value indirectly, 277 * through a pointer 278 * 279 * This operator ensures that the OsclSingleton can be used like the 280 * regular pointer that it was initialized with. 281 */ 282 T *operator->() const 283 { 284 return(_Ptr); 285 } 286 287 288 /** 289 * @brief set() method sets ownership to the pointer, passed. 290 * This method is needed when the class is created with a default 291 * constructor. Returns false in case the class is non-empty. 292 * 293 */ set()294 bool set() 295 { 296 _Ptr = OSCL_STATIC_CAST(T*, Registry::getInstance(ID)); 297 return (_Ptr ? true : false); 298 } 299 300 }; 301 #endif //OSCL_HAS_SINGLETON_SUPPORT 302 303 #include "oscl_tls.h" 304 #include "oscl_assert.h" 305 class OsclTLSRegistryEx 306 { 307 public: 308 /* 309 ** Get an entry 310 ** @param ID: identifier 311 ** @returns: the entry value 312 ** @exception: leaves on error. 313 */ getInstance(uint32 ID)314 static OsclAny* getInstance(uint32 ID) 315 { 316 int32 error; 317 OsclAny* val = OsclTLSRegistry::getInstance(ID, error); 318 if (error) 319 { 320 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 321 OsclError::Leave(_OsclBaseToErrorMap[error]); 322 } 323 return val; 324 } 325 /* 326 ** Set an entry 327 ** @param ID: identifier 328 ** @returns: the entry value 329 ** @exception: leaves on error. 330 */ registerInstance(OsclAny * ptr,uint32 ID)331 static void registerInstance(OsclAny* ptr, uint32 ID) 332 { 333 int32 error; 334 OsclTLSRegistry::registerInstance(ptr, ID, error); 335 if (error) 336 { 337 OSCL_ASSERT(_OsclBaseToErrorMap[error]); 338 OsclError::Leave(_OsclBaseToErrorMap[error]); 339 } 340 } 341 }; 342 343 template < class T, uint32 ID, class Registry = OsclTLSRegistryEx > class OsclTLSEx 344 { 345 private: 346 // make the copy constructor and assignment operator private 347 OsclTLSEx& operator=(OsclTLSEx& _Y) 348 { 349 return(*this); 350 } 351 352 protected: 353 T* _Ptr; 354 355 public: OsclTLSEx()356 OsclTLSEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {}; 357 ~OsclTLSEx()358 ~OsclTLSEx() {}; 359 360 /** 361 * @brief The indirection operator (*) accesses a value indirectly, 362 * through a pointer 363 * 364 * This operator ensures that the OsclTLS can be used like the 365 * regular pointer that it was initialized with. 366 */ 367 T& operator*() const 368 { 369 return(*_Ptr); 370 } 371 372 /** 373 * @brief The indirection operator (->) accesses a value indirectly, 374 * through a pointer 375 * 376 * This operator ensures that the OsclTLS can be used like the 377 * regular pointer that it was initialized with. 378 */ 379 T *operator->() const 380 { 381 return(_Ptr); 382 } 383 384 385 /** 386 * @brief set() method sets ownership to the pointer, passed. 387 * This method is needed when the class is created with a default 388 * constructor. Returns false in case the class is non-empty. 389 * 390 */ set()391 bool set() 392 { 393 _Ptr = OSCL_STATIC_CAST(T*, Registry::getInstance(ID)); 394 return (_Ptr ? true : false); 395 } 396 397 }; 398 399 #endif 400 401 /*! @} */ 402