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

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 

OSCL API
Posting Version: OPENCORE_20090310