blob: 305d22fadfc402a8c39123f1b49d7d3e8e3384be [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// -*- c++ -*-
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// O S C L _ E R R O R _ I M P _ J U M P S
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/*! \addtogroup osclerror OSCL Error
*
* @{
*/
/** \file oscl_error_imp_jumps.h
\brief Implemenation of using Setjmp / Longjmp.
*/
#ifndef OSCL_ERROR_IMP_JUMPS_H_INCLUDED
#define OSCL_ERROR_IMP_JUMPS_H_INCLUDED
#ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
#include "oscl_error_trapcleanup.h"
#endif
#ifndef OSCL_ASSERT_H_INCLUDED
#include "oscl_assert.h"
#endif
// Implemenation of Leave using Setjmp / Longjmp.
//ANSI setjmp/longjmp implementation. This is needed on any OS
//that does not support C++ exceptions. This is a complete implementation.
#ifndef OSCLCONFIG_ERROR_H_INCLUDED
#include "osclconfig_error.h"
#endif
#ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
#include "oscl_error_trapcleanup.h"
#endif
#ifndef OSCL_DEFALLOC_H_INCLUDED
#include "oscl_defalloc.h"
#endif
#ifndef OSCL_ERROR_H_INCLUDED
#include "oscl_error.h"
#endif
class Oscl_DefAlloc;
//this defines the maximum depth of the jump mark stack.
#define OSCL_JUMP_MAX_JUMP_MARKS OSCL_MAX_TRAP_LEVELS
//OsclJump class
class OsclJump
{
public:
//for use in macros only.
OSCL_IMPORT_REF static void StaticJump(int a);
void Jump(int a)
{
if (!Top())
{
//Note: you can't leave here, since leave would
//invoke this routine again. It is not safe to return
//either, because calling code is expecting an execution
//end.
OSCL_ASSERT(false);
_OSCL_Abort();
}
longjmp(*Top(), a);
}
jmp_buf *Top()
{
OSCL_ASSERT(iJumpIndex >= 0);
return &iJumpArray[iJumpIndex];
}
~OsclJump()
{
//jump mark stack should be empty at this point.
OSCL_ASSERT(iJumpIndex == (-1));
}
private:
OsclJump(): iJumpIndex(-1) {}
void PushMark()
{
OSCL_ASSERT(iJumpIndex < (OSCL_JUMP_MAX_JUMP_MARKS - 1));//jump stack is full!
iJumpIndex++;
}
void PopMark()
{
OSCL_ASSERT(iJumpIndex >= 0);//jump stack is empty!
iJumpIndex--;
}
jmp_buf iJumpArray[OSCL_JUMP_MAX_JUMP_MARKS];
//index to top of stack, or (-1) when stack is empty
int32 iJumpIndex;
friend class OsclErrorTrapImp;
};
//internal jump type codes.
#define internalLeave (-1)
//Leave uses the OsclJump methods
#define PVError_DoLeave() OsclJump::StaticJump(internalLeave)
//_PV_TRAP macro catches leaves.
//_r is leave code, _s is statements to execute.
#define _PV_TRAP(__r,__s)\
__r=OsclErrNone;\
{\
OsclErrorTrapImp* __trap=OsclErrorTrapImp::Trap();\
if(!__trap){__s;}else{\
int __tr=setjmp(*(__trap->iJumpData->Top()));\
if (__tr==0)\
{__s;}\
else if (__tr==internalLeave)\
{__r=__trap->iLeave;}\
__trap->UnTrap();}\
}
//Same as _PV_TRAP but avoids a TLS lookup.
// __trapimp is the OsclErrorTrapImp* for the calling thread.
#define _PV_TRAP_NO_TLS(__trapimp,__r,__s)\
__r=OsclErrNone;\
{\
OsclErrorTrapImp* __trap=OsclErrorTrapImp::TrapNoTls(__trapimp);\
if(!__trap){__s;}else{\
int __tr=setjmp(*(__trap->iJumpData->Top()));\
if (__tr==0)\
{__s;}\
else if (__tr==internalLeave)\
{__r=__trap->iLeave;}\
__trap->UnTrap();}\
}
#endif // OSCL_ERROR_IMP_JUMPS_H_INCLUDED
/*! @} */