提交 4826a185 编写于 作者: weixin_48148422's avatar weixin_48148422

TD-153: add defer support

上级 736ddfbb
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
* Copyright (c) 2020 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
......@@ -17,33 +17,81 @@
#define TDENGINE_EXCEPTION_H
#include <setjmp.h>
#include <stdint.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* exception handling
*/
typedef struct SExceptionNode {
struct SExceptionNode* prev;
jmp_buf jb;
int code;
} SExceptionNode;
void expPushNode( SExceptionNode* node );
int expPopNode();
void expThrow( int code );
void exceptionPushNode( SExceptionNode* node );
int exceptionPopNode();
void exceptionThrow( int code );
#define THROW( x ) exceptionThrow( (x) )
#define CAUGHT_EXCEPTION() (caught_exception == 1)
#define TRY do { \
SExceptionNode expNode = { 0 }; \
expPushNode( &expNode ); \
if( setjmp(expNode.jb) == 0 ) {
exceptionPushNode( &expNode ); \
int caught_exception = setjmp(expNode.jb); \
if( caught_exception == 0 )
#define CATCH( code ) int code = exceptionPopNode(); \
if( caught_exception == 1 )
#define FINALLY( code ) int code = exceptionPopNode();
#define END_TRY } while( 0 );
/*
* defered operations
*/
typedef struct SDeferedOperation {
void (*wrapper)( struct SDeferedOperation* dp );
void* func;
void* arg;
} SDeferedOperation;
void deferExecute( SDeferedOperation* operations, unsigned int numOfOperations );
void deferWrapper_void_void( SDeferedOperation* dp );
void deferWrapper_void_ptr( SDeferedOperation* dp );
void deferWrapper_int_int( SDeferedOperation* dp );
#define DEFER_INIT( MaxOperations ) unsigned int maxDeferedOperations = MaxOperations, numOfDeferedOperations = 0; \
SDeferedOperation deferedOperations[MaxOperations]
#define DEFER_PUSH( wrapperFunc, deferedFunc, argument ) do { \
assert( numOfDeferedOperations < maxDeferedOperations ); \
SDeferedOperation* dp = deferedOperations + numOfDeferedOperations++; \
dp->wrapper = wrapperFunc; \
dp->func = (void*)deferedFunc; \
dp->arg = (void*)argument; \
} while( 0 )
#define DEFER_POP() do { --numOfDeferedOperations; } while( 0 )
#define CATCH( code ) expPopNode(); \
} else { \
int code = expPopNode();
#define DEFER_EXECUTE() do{ \
deferExecute( deferedOperations, numOfDeferedOperations ); \
numOfDeferedOperations = 0; \
} while( 0 )
#define END_CATCH } } while( 0 );
#define DEFER_PUSH_VOID_PTR( func, arg ) DEFER_PUSH( deferWrapper_void_ptr, func, arg )
#define DEFER_PUSH_INT_INT( func, arg ) DEFER_PUSH( deferWrapper_int_int, func, arg )
#define DEFER_PUSH_VOID_VOID( func ) DEFER_PUSH( deferWrapper_void_void, func, 0 )
#define THROW( x ) expThrow( (x) )
#define DEFER_PUSH_FREE( arg ) DEFER_PUSH( deferWrapper_void_ptr, free, arg )
#define DEFER_PUSH_CLOSE( arg ) DEFER_PUSH( deferWrapper_int_int, close, arg )
#ifdef __cplusplus
}
......
......@@ -3,18 +3,41 @@
static _Thread_local SExceptionNode* expList;
void expPushNode( SExceptionNode* node ) {
void exceptionPushNode( SExceptionNode* node ) {
node->prev = expList;
expList = node;
}
int expPopNode() {
int exceptionPopNode() {
SExceptionNode* node = expList;
expList = node->prev;
return node->code;
}
void expThrow( int code ) {
void exceptionThrow( int code ) {
expList->code = code;
longjmp( expList->jb, 1 );
}
void deferWrapper_void_ptr( SDeferedOperation* dp ) {
void (*func)( void* ) = dp->func;
func( dp->arg );
}
void deferWrapper_int_int( SDeferedOperation* dp ) {
int (*func)( int ) = dp->func;
func( (int)(intptr_t)(dp->arg) );
}
void deferWrapper_void_void( SDeferedOperation* dp ) {
void (*func)() = dp->func;
func();
}
void deferExecute( SDeferedOperation* operations, unsigned int numOfOperations ) {
while( numOfOperations > 0 ) {
--numOfOperations;
SDeferedOperation* dp = operations + numOfOperations;
dp->wrapper( dp );
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册