greenplumn except 源码
greenplumn except 代码
文件路径:/gpcontrib/gpmapreduce/include/except.h
#ifndef EXCEPT_H
#define EXCEPT_H
#ifndef SETJMP_H
#include <setjmp.h>
#endif
#ifndef STDIO_H
#include <stdio.h>
#endif
/*
* except.h - A very simplistic exception handling framework
*
* This exception system makes use of a global linked list of exception
* frames and thus is not threadsafe!
*
* It's also probably not safe to nest try blocks within a single function.
*
* Usage:
*
* // in main.c
* ALLOW_EXCEPTIONS;
*
* int main(...) {...}
*
* // elsewhere
* void myfunction(...)
* {
* ...
*
* XTRY
* {
* ...
* some_other_function(...)
* ...
* }
* XCATCH(errcode)
* {
* // handle an expected exception code
* printf(xframe.exception);
* }
* XCATCH_ANY
* {
* XRERAISE()
* }
* XFINALLY
* {
* ...
* }
* XTRY_END;
*
* ...
* }
*
* void some_other_function(...)
* {
* ...
* XRAISE(errcode, "errmsg");
* }
*
*/
typedef struct xframe_ xframe_t;
struct xframe_
{
jmp_buf jumper;
xframe_t *next;
volatile int errcode;
volatile void *exception;
volatile int state;
volatile char *file;
volatile int lineno;
};
#define XFRAME_BASE 0x00000000
#define XFRAME_HANDLED 0x00000001
#define XFRAME_ANY 0x00000002
#define XFRAME_FINAL 0x00000004
/* The global exception frame */
extern xframe_t *global_exception_frame;
/* Declare this someplace global in main.c */
#define ALLOW_EXCEPTIONS \
xframe_t *global_exception_frame = NULL
/* we use MAX INT for the finnally errcode */
#define ERRCODE_FOR_FINALLY_BLOCK 2147483647
#define ERRCODE_FOR_EXIT_BLOCK 2147483646
#define ERRCODE_FOR_ANY_BLOCK 2147483645
#define ASSERTION_FAILURE 2147483644
#define XRAISE(ecode, v) \
do { \
if (!global_exception_frame) { \
fprintf(stderr, "Error: (%d) Unhandled Exception\n", \
ecode); \
fprintf(stderr, "Raised from %s at line %d\n", \
__FILE__, __LINE__); \
exit(1); \
} \
global_exception_frame->state = XFRAME_BASE; \
global_exception_frame->errcode = ecode; \
global_exception_frame->exception = (void *) v; \
global_exception_frame->file = (char*) __FILE__; \
global_exception_frame->lineno = __LINE__; \
longjmp(global_exception_frame->jumper, ecode); \
} while(0)
/*
* Note that if the final frame hasn't been executed then we long
* jump back to the finaly block. Before we do this we set the
* frame state to FRAME_FINAL to ensure that the FRAME_HANDLED flag
* is cleared, this is better than setting to FRAME_BASE only when
* there isn't a final block defined.
*/
#define XRERAISE() \
do { \
if (!xframe.errcode) { \
fprintf(stderr, "Error: Can't reraise null exception"); \
fprintf(stderr, "Raised from %s at line %d\n", \
xframe.file, xframe.lineno); \
exit(1); \
} \
if (!(xframe.state & XFRAME_FINAL)) { \
xframe.state = XFRAME_FINAL; \
longjmp(xframe.jumper, ERRCODE_FOR_FINALLY_BLOCK); \
} \
global_exception_frame = xframe.next; \
if (!global_exception_frame) { \
fprintf(stderr, "Error: (%d) Unhandled Exception\n", \
xframe.errcode); \
fprintf(stderr, "Raised from %s:%d\n", \
xframe.file, xframe.lineno); \
fprintf(stderr, "Current frame at %s:%d\n", \
__FILE__, __LINE__); \
exit(1); \
} \
global_exception_frame->state = XFRAME_BASE; \
global_exception_frame->errcode = xframe.errcode; \
global_exception_frame->exception = xframe.exception; \
global_exception_frame->file = xframe.file; \
global_exception_frame->lineno = xframe.lineno; \
longjmp(global_exception_frame->jumper, xframe.errcode); \
} while(0)
/*
* A simple built in assertion macro
*/
#define XASSERT(x) \
do { \
if (!(x)) \
{ \
if (!global_exception_frame) \
{ \
fprintf(stderr, "Error: Assertion failure at %s:%d\n", \
__FILE__, __LINE__); \
fprintf(stderr, "No exception recovery stack found\n"); \
} \
else \
{ \
XRAISE(ASSERTION_FAILURE, NULL); \
} \
} \
} while(0)
#define XTRY \
do { \
xframe_t xframe; \
xframe.errcode = 0; \
xframe.exception = NULL; \
xframe.next = global_exception_frame; \
xframe.state = XFRAME_BASE; \
global_exception_frame = &xframe; \
switch (setjmp(xframe.jumper)) \
{ \
case 0:
#define XCATCH(x) \
longjmp(xframe.jumper, ERRCODE_FOR_EXIT_BLOCK); \
case x: \
xframe.state |= XFRAME_HANDLED;
#define XCATCH_ANY \
longjmp(xframe.jumper, ERRCODE_FOR_EXIT_BLOCK); \
case ERRCODE_FOR_ANY_BLOCK: \
xframe.state |= XFRAME_HANDLED;
#define XFINALLY \
longjmp(xframe.jumper, ERRCODE_FOR_EXIT_BLOCK); \
case ERRCODE_FOR_FINALLY_BLOCK: \
global_exception_frame = xframe.next; \
xframe.state |= XFRAME_FINAL;
/*
* XTRY_END
*
* 1) If we fell through, or got called directly mark the 'any' block
* as hit since some CATCH statement must have been hit (or there
* are none and it doesn't matter.
*
* 2) If we hit the default block then try to call the ANY block,
* if it doesn't exist we'll just fall right back here again.
*
* 3) If we haven't hit the FINALLY block yet, do so now, if none
* we will fall back into the default case.
*
* 4) Once both ANY and FINALLY blocks have been dealt with we just
* need to clean up a bit. Pop the exception frame off the stack
* and if the exception wasn't handled then we have to reraise it.
*/
#define XTRY_END \
case ERRCODE_FOR_EXIT_BLOCK: \
xframe.state |= XFRAME_ANY; \
default: \
if (!(xframe.state & XFRAME_ANY)) \
{ \
xframe.state |= XFRAME_ANY; \
longjmp(xframe.jumper, ERRCODE_FOR_ANY_BLOCK); \
} \
if (!(xframe.state & XFRAME_FINAL)) \
{ \
xframe.state |= XFRAME_FINAL; \
longjmp(xframe.jumper, ERRCODE_FOR_FINALLY_BLOCK); \
} \
break; \
} \
global_exception_frame = xframe.next; \
if (!(xframe.state & XFRAME_HANDLED) && xframe.errcode) \
XRERAISE(); \
} while (0)
#endif
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦