blob: c585eb16495aac3bde138754a06dcf9e58ca3c4d [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 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 _ T R A P C L E A N U P
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/*! \addtogroup osclerror OSCL Error
*
* @{
*/
/** \file oscl_error_trapcleanup.h
\brief OSCL Error trap and cleanup implementation include file
*/
#ifndef OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
#define OSCL_ERROR_TRAPCLEANUP_H_INCLUDED
#ifndef OSCLCONFIG_ERROR_H_INCLUDED
#include "osclconfig_error.h"
#endif
#ifndef OSCL_HEAPBASE_H_INCLUDED
#include "oscl_heapbase.h"
#endif
#define OSCL_MAX_TRAP_LEVELS 20
/**
//Internal cleanup stack item type.
*/
class OsclTrapStackItem
{
public:
OsclTrapStackItem() {}
OsclTrapStackItem(OsclHeapBase *aCBase)
{
iCBase = aCBase;
iTAny = (OsclAny*)aCBase;
iTrapOperation = NULL;
iNext = NULL;
}
OsclTrapStackItem(OsclAny *aTAny)
{
iCBase = NULL;
iTAny = aTAny;
iTrapOperation = NULL;
iNext = NULL;
}
OsclTrapStackItem(OsclTrapItem aItem)
{
iCBase = NULL;
iTAny = aItem.iPtr;
iTrapOperation = aItem.iOperation;
iNext = NULL;
}
OsclHeapBase *iCBase;
OsclAny *iTAny;
OsclTrapOperation iTrapOperation;
OsclTrapStackItem *iNext;
};
class OsclJump;
#ifndef OSCL_ERROR_IMP_H_INCLUDED
#include "oscl_error_imp.h"
#endif
#ifndef OSCL_DEFALLOC_H_INCLUDED
#include "oscl_defalloc.h"
#endif
#ifndef OSCL_ASSERT_H_INCLUDED
#include "oscl_assert.h"
#endif
#ifndef OSCL_ERROR_H_INCLUDED
#include "oscl_error.h"
#endif
/**
//A common type for cleanup stack and trap mark stack.
//for internal use only.
*/
class OsclTrapStack
{
private:
OsclTrapStack(Oscl_DefAlloc *iAlloc);
~OsclTrapStack();
//Trap APIs
inline void Trap();
inline bool UnTrap();
//Cleanup stack APIs
void PushL(OsclHeapBase *aCBase);
void PushL(OsclAny *aTAny);
void PushL(OsclTrapItem anItem);
void Push(OsclTrapStackItem *aItem);
void Pop();
void Pop(int32 aCount);
void PopDealloc();
void PopDealloc(int32 aCount);
void Leaving();
//top of cleanup stack
OsclTrapStackItem *iTop;
//cleanup stack allocator.
Oscl_DefAlloc *iAlloc;
friend class OsclError;
friend class OsclErrorTrap;
friend class OsclErrorTrapImp;
private:
//The trap mark stack is a stack used to mark the top of the cleanup stack
//for each trap level.
inline void PushTrapL(OsclAny *aTAny);
inline void PopTrap();
//top of trap mark stack
OsclTrapStackItem *TrapTop()
{
if (iTrapTopIndex >= 0)
return &iTrapTopArray[iTrapTopIndex];
return NULL;
}
OsclTrapStackItem iTrapTopArray[OSCL_MAX_TRAP_LEVELS];
//index to top of stack, or (-1) when stack is empty
int32 iTrapTopIndex;
void pushTrapIndex()
{
if (iTrapTopIndex == (OSCL_MAX_TRAP_LEVELS - 1))
PV_EXECPANIC(ETrapNoFreeSlotItem);//stack is full.
else
iTrapTopIndex++;
}
void popTrapIndex()
{
if (iTrapTopIndex < 0)
PV_EXECPANIC(ETrapPopUnderflow);
else
iTrapTopIndex--;
}
};
#ifndef OSCL_ERROR_PANIC_H_INCLUDED
#include "oscl_error_panic.h"
#endif
#ifndef OSCL_BASE_ALLOC_H_INCLUDED
#include "oscl_base_alloc.h"
#endif
//For non-symbian, the error trap stack must be in a global registry.
//
//use TLS registry unless it's not available, then
//use singleton.
#include "oscl_tls.h"
#define PVERRORTRAP_REGISTRY_ID OSCL_TLS_ID_PVERRORTRAP
#define PVERRORTRAP_REGISTRY OsclTLSRegistry
/**
//A per-thread cleanup stack with nested trap support.
*/
class OsclErrorTrapImp
{
public:
/**
//these are used in public macros, but
//aren't intended as public methods or members.
*/
OSCL_IMPORT_REF void UnTrap();
#if defined(PVERROR_IMP_JUMPS)
OsclJump *iJumpData;
#endif
//Global leave/panic info.
TPVErrorPanic iPanic;
int32 iLeave;
public:
/**
//PV trap cleanup. Public for use in macros only.
*/
OSCL_IMPORT_REF static OsclErrorTrapImp* Trap();
//This version of Trap is identical to the above, except it avoids the TLS lookup.
OSCL_IMPORT_REF static OsclErrorTrapImp* TrapNoTls(OsclErrorTrapImp*);
OsclTrapStack *iTrapStack;
private:
OsclErrorTrapImp(Oscl_DefAlloc *aAlloc, int32 &error);
~OsclErrorTrapImp();
Oscl_DefAlloc *iAlloc;
static OsclErrorTrapImp* GetErrorTrap(int32& aError)
//static function to get currently installed error trap
//for this thread.
{
OsclErrorTrapImp *current = (OsclErrorTrapImp*)PVERRORTRAP_REGISTRY::getInstance(PVERRORTRAP_REGISTRY_ID, aError);
return current;
}
static OsclErrorTrapImp* GetErrorTrap()
//static function to get currently installed error trap
//for this thread. panics on error.
{
int32 error;
OsclErrorTrapImp* current = GetErrorTrap(error);
if (error)
{
OSCL_ASSERT(0);
return NULL;
}
return current;
}
static OsclErrorTrapImp* SetErrorTrap(OsclErrorTrapImp* a, int32& aError)
//static function to set currently installed error trap
//for this thread. return previous error trap, if any.
{
OsclErrorTrapImp* temp = GetErrorTrap(aError);
PVERRORTRAP_REGISTRY::registerInstance(a, PVERRORTRAP_REGISTRY_ID, aError);
return temp;
}
//Global cleanup function for OsclAny items.
static void TrapOperation(OsclAny *ptr)
{
int32 error;
OsclErrorTrapImp *trap = GetErrorTrap(error);
if (trap && trap->iAlloc)
trap->iAlloc->deallocate(ptr);
else
{
_OsclBasicAllocator alloc;
alloc.deallocate(ptr);
}
}
//default allocators.
_OsclBasicAllocator iDefAlloc;
friend class OsclErrorTrap;
friend class OsclError;
friend class OsclExecScheduler;
friend class OsclExecSchedulerCommonBase;
friend class OsclJump;
friend class OsclJumpMark;
friend class OsclTrapStack;
friend class CPVInterfaceProxy;
friend class OsclScheduler;
};
#endif
/*! @} */