Main Page Modules Class Hierarchy Data Structures File List Data Fields Globals Related Pages

# oscl_error_imp_jumps.h

Go to the documentation of this file.

    00001 // -*- c++ -*-
    00002 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    00003
    00004 //               O S C L _ E R R O R _ I M P _ J U M P S
    00005
    00006 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    00007
    00018 #ifndef OSCL_ERROR_IMP_JUMPS_H_INCLUDED
    00019 #define OSCL_ERROR_IMP_JUMPS_H_INCLUDED
    00020
    00021 #ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
    00022 #include "oscl_error_trapcleanup.h"
    00023 #endif
    00024 #ifndef OSCL_ASSERT_H_INCLUDED
    00025 #include "oscl_assert.h"
    00026 #endif
    00027
    00028 // Implemenation of Leave using Setjmp / Longjmp.
    00029
    00030 //ANSI setjmp/longjmp implementation.  This is needed on any OS
    00031 //that does not support C++ exceptions.  This is a complete implementation.
    00032
    00033 #ifndef OSCLCONFIG_ERROR_H_INCLUDED
    00034 #include "osclconfig_error.h"
    00035 #endif
    00036
    00037 #ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
    00038 #include "oscl_error_trapcleanup.h"
    00039 #endif
    00040 #ifndef OSCL_DEFALLOC_H_INCLUDED
    00041 #include "oscl_defalloc.h"
    00042 #endif
    00043 #ifndef OSCL_ERROR_H_INCLUDED
    00044 #include "oscl_error.h"
    00045 #endif
    00046
    00047 class Oscl_DefAlloc;
    00048
    00049 //this defines the maximum depth of the jump mark stack.
    00050 #define OSCL_JUMP_MAX_JUMP_MARKS OSCL_MAX_TRAP_LEVELS
    00051
    00052
    00053 //OsclJump class
    00054 class OsclJump
    00055 {
    00056     public:
    00057         //for use in macros only.
    00058
    00059         OSCL_IMPORT_REF static void StaticJump(int a);
    00060
    00061         void Jump(int a)
    00062         {
    00063             if (!Top())
    00064             {
    00065                 //Note: you can't leave here, since leave would
    00066                 //invoke this routine again.  It is not safe to return
    00067                 //either, because calling code is expecting an execution
    00068                 //end.
    00069                 OSCL_ASSERT(false);
    00070                 _OSCL_Abort();
    00071             }
    00072             longjmp(*Top(), a);
    00073         }
    00074
    00075         jmp_buf *Top()
    00076         {
    00077             OSCL_ASSERT(iJumpIndex >= 0);
    00078             return &iJumpArray[iJumpIndex];
    00079         }
    00080
    00081         ~OsclJump()
    00082         {
    00083             //jump mark stack should be empty at this point.
    00084             OSCL_ASSERT(iJumpIndex == (-1));
    00085         }
    00086
    00087     private:
    00088         OsclJump(): iJumpIndex(-1) {}
    00089
    00090         void PushMark()
    00091         {
    00092             OSCL_ASSERT(iJumpIndex < (OSCL_JUMP_MAX_JUMP_MARKS - 1));//jump stack is full!
    00093             iJumpIndex++;
    00094         }
    00095
    00096         void PopMark()
    00097         {
    00098             OSCL_ASSERT(iJumpIndex >= 0);//jump stack is empty!
    00099             iJumpIndex--;
    00100         }
    00101
    00102         jmp_buf iJumpArray[OSCL_JUMP_MAX_JUMP_MARKS];
    00103
    00104         //index to top of stack, or (-1) when stack is empty
    00105         int32 iJumpIndex;
    00106
    00107         friend class OsclErrorTrapImp;
    00108 };
    00109
    00110
    00111 //internal jump type codes.
    00112 #define internalLeave (-1)
    00113
    00114 //Leave uses the OsclJump methods
    00115 #define PVError_DoLeave() OsclJump::StaticJump(internalLeave)
    00116
    00117 //_PV_TRAP macro catches leaves.
    00118 //_r is leave code, _s is statements to execute.
    00119 #define _PV_TRAP(__r,__s)\
    00120     __r=OsclErrNone;\
    00121     {\
    00122         OsclErrorTrapImp* __trap=OsclErrorTrapImp::Trap();\
    00123         if(!__trap){__s;}else{\
    00124         int __tr=setjmp(*(__trap->iJumpData->Top()));\
    00125         if (__tr==0)\
    00126         {__s;}\
    00127         else if (__tr==internalLeave)\
    00128         {__r=__trap->iLeave;}\
    00129         __trap->UnTrap();}\
    00130     }
    00131
    00132 //Same as _PV_TRAP but avoids a TLS lookup.
    00133 // __trapimp is the OsclErrorTrapImp* for the calling thread.
    00134 #define _PV_TRAP_NO_TLS(__trapimp,__r,__s)\
    00135     __r=OsclErrNone;\
    00136     {\
    00137         OsclErrorTrapImp* __trap=OsclErrorTrapImp::TrapNoTls(__trapimp);\
    00138         if(!__trap){__s;}else{\
    00139         int __tr=setjmp(*(__trap->iJumpData->Top()));\
    00140         if (__tr==0)\
    00141         {__s;}\
    00142         else if (__tr==internalLeave)\
    00143         {__r=__trap->iLeave;}\
    00144         __trap->UnTrap();}\
    00145     }
    00146
    00147
    00148 #endif // OSCL_ERROR_IMP_JUMPS_H_INCLUDED
    00149