head 2.2; access; symbols V4_1_1_1:2.2 Rel_2_1:2.1; locks; strict; comment @ @; 2.2 date 2001.01.25.12.12.46; author cibrario; state Exp; branches; next 2.1; 2.1 date 2000.05.26.14.45.04; author cibrario; state Rel; branches; next 1.6; 1.6 date 97.01.15.13.44.39; author cibrario; state Exp; branches; next 1.1; 1.1 date 96.05.28.12.54.28; author cibrario; state Beta; branches; next ; desc @This module implements the CHF functions ChfPushHandler() and ChfPopHandler() @ 2.2 log @Added partial Win32 support (Windows CE only). @ text @/* .+ .identifier : $Id: chf_hdlr.c,v 2.1 2000/05/26 14:45:04 cibrario Rel cibrario $ .context : CHF, Condition Handling Facility .title : $RCSfile: chf_hdlr.c,v $, condition generation .kind : C source .author : Ivan Cibrario B. .site : CSTV-CNR .creation : 3-May-1996 .keywords : * .description : This module implements the CHF functions ChfPushHandler() and ChfPopHandler() .include : Chf.h .notes : $Log: chf_hdlr.c,v $ Revision 2.1 2000/05/26 14:45:04 cibrario - Implemented StructuredHelper(), the structured condition handling helper handler - Updated ChfPushHandler() to push the structured condition handling helper when new_handler is CHF_NULL_HANDLER - unwind_context is now a sigjmp_buf, passed as argument directly, that is, without additional address operators - improved documentation of ChfPopHandler() Revision 1.6 1997/01/15 13:44:39 cibrario The function ChfPushHandler() has the new argument 'handler_context'. Revision 1.1 1996/05/28 12:54:28 cibrario Initial revision .- */ #ifndef lint static char rcs_id[] = "$Id: chf_hdlr.c,v 2.1 2000/05/26 14:45:04 cibrario Rel cibrario $"; #endif #include #include #ifndef _WIN32 #include #endif #include #ifdef _WIN32 #include #include #endif #include "Chf.h" #include "ChfPriv.h" /* .+ .title : StructuredHelper .kind : C function .creation : 19-May-2000 .description : This function is the structured condition handling helper of CHF. It's automatically pushed into the condition handler stack by ChfPushHandler() when its 'new_handler' argument is CHF_NULL_HANDLER, and performs the following functions: - if called during an ordinary signalling operation with a CHF_FATAL condition, it requests the action CHF_UNWIND_KEEP - if called when Chf is in any other state, or with a severity less than CHF_FATAL, it requests the action CHF_RESIGNAL The structured condition handling helper currently makes no use of handler_context. .call : action = StructuredHelper(desc, state, context); .input : const ChfDescriptor *desc, condition descriptor const ChfState state, current CHF state .output : ChfAction action, action requested by the handler .status_codes : none .notes : 2.1, 19-May-2000, creation .- */ static ChfAction StructuredHelper( const ChfDescriptor *desc, const ChfState state, ChfPointer handler_context ) { ChfAction action; const ChfDescriptor *d; return((state == CHF_SIGNALING && ChfGetSeverity(desc) == CHF_FATAL) ? CHF_UNWIND_KEEP : CHF_RESIGNAL); } /* .+ .title : ChfPushHandler .kind : C function .creation : 13-May-1996 .description : This function pushes the new condition handler 'new_handler' with its associated longjmp context pointed by 'unwind_context' into the handler stack and returns CHF_S_OK to the caller. If 'new_handler' is CHF_NULL_HANDLER, the special structured condition handling helper 'StructuredHelper()' is pushed instead. Moreover, this function saves a copy of the pointer 'handler_context'; it will be passed to 'new_handler' upon each subsequent activation, and therefore can be used as a private handler context pointer. The user must assure that the information pointed by 'handler_context', if any, will remain valid until 'new_handler' is popped from the condition stack. 'handler_context' may be set to the special (null) value CHF_NULL_POINTER to indicate that the handler hasn't any private context information. If, in the future, the handler will request the CHF_UNWIND action, the setjmp() function invocation that established 'unwind_context' will appear to return again. 'unwind_context' can be the reserved (null) pointer CHF_NULL_CONTEXT; in this case, if the handler will request the CHF_UNWIND_ACTION, the application will be silently terminated calling ChfAbort() with abort code CHF_ABORT_SILENT. If some error occours during the execution, the function will generate and immediately signal one of the conditions listed below and marked with (*). The function will never return dorectly to the caller, since all conditions are CHF_FATAL. NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if the CHF subsystem has not been initialized. .call : ChfPushHandler(new_handler, unwind_context); .input : ChfHandler new_handler, new condition handler void *unwind_context, handler unwind context pointer ChfPointer handler_context, private handler context pointer .output : void .status_codes : (*) CHF_F_BAD_STATE, bad CHF state for requested operation (*) CHF_F_HDLR_STACK_FULL, the handler stack is full .notes : 1.1, 13-May-1996, creation 1.6, 15-Jan-1997, update: - added the argument 'handler_context' - improved documentation 2.1, 19-May-2000, update: - now using sigjmp_buf as unwind_context - added StructuredHelper handling .- */ void ChfPushHandler( /* Push a new handler into the stack */ ChfHandler new_handler, void *unwind_context, ChfPointer handler_context ) { /* Make sure that CHF has been correctly initialized and is idle */ if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT); if(chf_context.state != CHF_IDLE) { ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd; ChfSignal(); } /* Check if the handler stack is full */ else if(chf_context.handler_sp - chf_context.handler_stack >= chf_context.handler_stack_size) { ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL ChfEnd; ChfSignal(); } else { chf_context.handler_sp->unwind_context = unwind_context; chf_context.handler_sp->handler_context = handler_context; chf_context.handler_sp->handler = ((new_handler == CHF_NULL_HANDLER) ? StructuredHelper : new_handler); chf_context.handler_sp++; } } /* .+ .title : ChfPopHandler .kind : C function .creation : 13-May-1996 .description : This function pops the topmost condition handler from the handler stack and returns to the caller. If some error occours during the execution, the function will generate and immediately signal one of the conditions listed below and marked with (*). The function will never return directly to the caller, since all conditions are CHF_FATAL. NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if the CHF subsystem has not been initialized. .call : ChfPopHandler(); .input : void .output : void .status_codes : CHF_F_BAD_STATE, bad CHF state for requested operation CHF_F_HDLR_STACK_FULL, the handler stack is full .notes : 1.1, 13-May-1996, creation 1.6, 15-Jan-1997, update: - improved documentation 2.1, 19-May-2000, update: - improved documentation .- */ void ChfPopHandler( /* Pop a handler */ void ) { /* Make sure that CHF has been correctly initialized and is idle */ if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT); if(chf_context.state != CHF_IDLE) { ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd; ChfSignal(); } /* Check if the handler stack is empty */ else if(chf_context.handler_sp == chf_context.handler_stack) { ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL ChfEnd; ChfSignal(); } /* Discard the topmost condition handler */ else --chf_context.handler_sp; } @ 2.1 log @- Implemented StructuredHelper(), the structured condition handling helper handler - Updated ChfPushHandler() to push the structured condition handling helper when new_handler is CHF_NULL_HANDLER - unwind_context is now a sigjmp_buf, passed as argument directly, that is, without additional address operators - improved documentation of ChfPopHandler() @ text @d3 1 a3 1 .identifier : $Id: chf_hdlr.c,v 1.6 1997/01/15 13:44:39 cibrario Exp cibrario $ d19 9 d38 1 a38 1 static char rcs_id[] = "$Id: chf_hdlr.c,v 1.6 1997/01/15 13:44:39 cibrario Exp cibrario $"; d43 1 d45 1 d48 5 @ 1.6 log @The function ChfPushHandler() has the new argument 'handler_context'. @ text @d3 1 a3 1 .identifier : $Id: chf_hdlr.c,v 1.1 1996/05/28 12:54:28 cibrario Beta $ d19 3 d29 1 a29 1 static char rcs_id[] = "$Id: chf_hdlr.c,v 1.1 1996/05/28 12:54:28 cibrario Beta $"; d43 47 d96 3 a98 1 stack and returns CHF_S_OK to the caller. d129 1 a129 1 jmp_buf *unwind_context, handler unwind context pointer d141 3 d148 1 a148 1 jmp_buf *unwind_context, d177 2 a178 1 chf_context.handler_sp->handler = new_handler; d202 1 a202 1 ChfPopHandler(new_handler); d204 1 a204 1 const int abort_code, abort_code d214 2 @ 1.1 log @Initial revision @ text @d3 1 a3 1 .identifier : $Id$ d5 1 a5 1 .title : $RCSfile$, condition generation d18 3 a20 1 $Log$ d22 1 d26 1 a26 1 static char rcs_id[] = "$Id$"; d47 8 d74 1 a74 1 cc = ChfPushHandler(new_handler, unwind_context); d76 3 a78 3 ChfHandler new_handler, jmp_buf *unwind_context const int abort_code, abort_code d80 1 a80 1 int cc, condition code d86 3 d93 2 a94 1 jmp_buf *unwind_context d121 1 d150 1 a150 1 int cc, condition code a153 1 CHF_I_UNWIND_DONE, unwind succesfully completed d156 2 @