FreeCalypso > hg > fc-tourmaline
diff src/cs/riviera/support/exception.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/riviera/support/exception.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,140 @@ +/* + ****************************** + * + * + * Initialial version: Laurent Deniau, Laurent.Deniau@cern.ch + * + * For more information, please see the paper: + * http://cern.ch/Laurent.Deniau/html/oopc/exception.html + * + * ----------------------------------------------------------- + * + * Strong rework and adaption to riviera by Christophe Favergeon + * + ****************************** + */ + +// Authorization to use this source code communicated to Christophe Favergeon +// by email + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include "support/exception.h" + +#ifndef _WINDOWS + #include "config/swconfig.cfg" +#endif + + +/* global stack of exception context */ +struct _exceptionContext_ *const _returnExceptionContext_[MAX_RVF_TASKS]= +#if (!GSMLITE) + {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +#else + {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +#endif + +struct _exceptionContext_ *_currentExceptionContext_ [MAX_RVF_TASKS]= +#if (!GSMLITE) + {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +#else + {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +#endif + +/* delete protected pointers and throw exception */ +void +_exceptionThrow_(int exception) +{ + struct _protectedPtr_ *p; + struct _protectedPtr_ *oldp; + + /* no exception context saved, exit program */ + if (!_currentExceptionContext_[rvf_get_taskid()]) exit(exception); + + /* free pointers stored on the current exception context pointers stack */ + p=_currentExceptionContext_[rvf_get_taskid()]->stack; + + while(p) + { + oldp=p->previous; + p->func(p->ptr); + rvf_free_buf(p); + p=oldp; + } + + _currentExceptionContext_[rvf_get_taskid()]->stack=NULL; + + /* jump to previous exception context */ + rvf_restore_context_buffer_(_currentExceptionContext_[rvf_get_taskid()]->context, exception); +} + + +// Protect a pointer when there is a try/ctahc block active +void rvf_protect_pointer(T_RVF_MB_ID mb_id,void *p,T_RVF_RELEASE_PROTECTED_POINTER func) +{ + + struct _protectedPtr_ *ptr; + struct _exceptionContext_ *context; + T_RVF_MB_STATUS err; + + + + if (_currentExceptionContext_[rvf_get_taskid()]) + { + + if (p==NULL) + throw(E_not_enough_memory); + + context=_currentExceptionContext_[rvf_get_taskid()]; + err=rvf_get_buf(mb_id,sizeof(struct _protectedPtr_),(void*)&ptr); + + + if (err==RVF_GREEN) + { + ptr->next=NULL; + ptr->previous=NULL; + ptr->ptr=p; + ptr->func=func; + + if (context->stack==NULL) + { + context->stack=ptr; + } + else + { + ptr->previous=context->stack; + context->stack->next=ptr; + context->stack=ptr; + } + } + else + { + if (p!=NULL) + rvf_free_buf(p); + throw(E_not_enough_memory); + } + } +} + +void rvf_forget_protected_ptr() +{ + struct _protectedPtr_ *p; + struct _protectedPtr_ *oldp; + + p=_currentExceptionContext_[rvf_get_taskid()]->stack; + + while(p) + { + oldp=p->previous; + rvf_free_buf(p); + p=oldp; + } + + _currentExceptionContext_[rvf_get_taskid()]->stack=NULL; +} + + +