Home | History | Annotate | Download | only in src
      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         */
    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         */
    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         */
    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         */
    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:
    259         OsclSingletonEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {};
    260 
    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         */
    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         */
    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         */
    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:
    356         OsclTLSEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {};
    357 
    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         */
    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