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

update defer and rename it to cleanup

上级 4826a185
......@@ -25,73 +25,87 @@ extern "C" {
#endif
/*
* exception handling
* cleanup actions
*/
typedef struct SCleanupAction {
bool failOnly;
uint8_t wrapper;
uint16_t reserved;
void* func;
union {
void* Ptr;
bool Bool;
char Char;
int8_t Int8;
uint8_t Uint8;
int16_t Int16;
uint16_t Uint16;
int Int;
unsigned int Uint;
int32_t Int32;
uint32_t Uint32;
int64_t Int64;
uint64_t Uint64;
float Float;
double Double;
} arg1, arg2;
} SCleanupAction;
void cleanupPush_void_ptr_ptr ( bool failOnly, void* func, void* arg1, void* arg2 );
void cleanupPush_void_ptr_bool ( bool failOnly, void* func, void* arg1, bool arg2 );
void cleanupPush_void_ptr ( bool failOnly, void* func, void* arg );
void cleanupPush_int_int ( bool failOnly, void* func, int arg );
void cleanupPush_void ( bool failOnly, void* func );
int32_t cleanupGetActionCount();
void cleanupExecute( bool failed, int32_t toIndex );
#define CLEANUP_PUSH_VOID_PTR_PTR( failOnly, func, arg1, arg2 ) cleanupPush_void_ptr_ptr( (failOnly), (void*)(func), (void*)(arg1), (void*)(arg2) )
#define CLEANUP_PUSH_VOID_PTR_BOOL( failOnly, func, arg1, arg2 ) cleanupPush_void_ptr_bool( (failOnly), (void*)(func), (void*)(arg1), (bool)(arg2) )
#define CLEANUP_PUSH_VOID_PTR( failOnly, func, arg ) cleanupPush_void_ptr( (failOnly), (void*)(func), (void*)(arg) )
#define CLEANUP_PUSH_INT_INT( failOnly, func, arg ) cleanupPush_void_ptr( (failOnly), (void*)(func), (int)(arg) )
#define CLEANUP_PUSH_VOID( failOnly, func ) cleanupPush_void( (failOnly), (void*)(func) )
#define CLEANUP_PUSH_FREE( failOnly, arg ) cleanupPush_void_ptr( (failOnly), free, (void*)(arg) )
#define CLEANUP_PUSH_CLOSE( failOnly, arg ) cleanupPush_int_int( (failOnly), close, (int)(arg) )
#define CLEANUP_CREATE_ANCHOR() int32_t cleanupAnchor = cleanupGetActionCount()
#define CLEANUP_EXECUTE( failed ) cleanupExecute( cleanupAnchor, (failed) )
/*
* exception hander registration
*/
typedef struct SExceptionNode {
struct SExceptionNode* prev;
jmp_buf jb;
int code;
int32_t code;
int32_t maxCleanupAction;
int32_t numCleanupAction;
SCleanupAction* cleanupActions;
} SExceptionNode;
void exceptionPushNode( SExceptionNode* node );
int exceptionPopNode();
int32_t exceptionPopNode();
void exceptionThrow( int code );
#define THROW( x ) exceptionThrow( (x) )
#define CAUGHT_EXCEPTION() (caught_exception == 1)
#define TRY do { \
SExceptionNode expNode = { 0 }; \
exceptionPushNode( &expNode ); \
int caught_exception = setjmp(expNode.jb); \
if( caught_exception == 0 )
#define TRY(maxCleanupActions) do { \
SExceptionNode exceptionNode = { 0 }; \
SDeferedOperation cleanupActions[maxCleanupActions > 0 ? maxCleanupActions : 1]; \
exceptionNode.maxCleanupAction = maxCleanupActions > 0 ? maxDefered : 1; \
exceptionNode.cleanupActions = cleanupActions; \
int32_t cleanupAnchor = 0; \
exceptionPushNode( &exceptionNode ); \
int caughtException = setjmp( exceptionNode.jb ); \
if( caughtException == 0 )
#define CATCH( code ) int code = exceptionPopNode(); \
if( caught_exception == 1 )
if( caughtEexception == 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 DEFER_EXECUTE() do{ \
deferExecute( deferedOperations, numOfDeferedOperations ); \
numOfDeferedOperations = 0; \
} 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 DEFER_PUSH_FREE( arg ) DEFER_PUSH( deferWrapper_void_ptr, free, arg )
#define DEFER_PUSH_CLOSE( arg ) DEFER_PUSH( deferWrapper_int_int, close, arg )
#define THROW( x ) exceptionThrow( (x) )
#define CAUGHT_EXCEPTION() ((bool)(caughtEexception == 1))
#ifdef __cplusplus
}
......
......@@ -8,7 +8,7 @@ void exceptionPushNode( SExceptionNode* node ) {
expList = node;
}
int exceptionPopNode() {
int32_t exceptionPopNode() {
SExceptionNode* node = expList;
expList = node->prev;
return node->code;
......@@ -19,25 +19,105 @@ void exceptionThrow( int code ) {
longjmp( expList->jb, 1 );
}
void deferWrapper_void_ptr( SDeferedOperation* dp ) {
void (*func)( void* ) = dp->func;
func( dp->arg );
static void cleanupWrapper_void_ptr_ptr( SCleanupAction* ca ) {
void (*func)( void*, void* ) = ac->func;
func( ca->arg1.Ptr, ca->arg2.Ptr );
}
static void cleanupWrapper_void_ptr_bool( SCleanupAction* ca ) {
void (*func)( void*, bool ) = ca->func;
func( ca->arg1.Ptr, ca->arg2.Bool );
}
void deferWrapper_int_int( SDeferedOperation* dp ) {
int (*func)( int ) = dp->func;
func( (int)(intptr_t)(dp->arg) );
static void cleanupWrapper_void_ptr( SCleanupAction* ca ) {
void (*func)( void* ) = ca->func;
func( ca->arg1.Ptr );
}
void deferWrapper_void_void( SDeferedOperation* dp ) {
void (*func)() = dp->func;
static void cleanupWrapper_int_int( SCleanupAction* ca ) {
int (*func)( int ) = ca->func;
func( (int)(intptr_t)(ca->arg1.Int) );
}
static void cleanupWrapper_void_void( SCleanupAction* ca ) {
void (*func)() = ca->func;
func();
}
void deferExecute( SDeferedOperation* operations, unsigned int numOfOperations ) {
while( numOfOperations > 0 ) {
--numOfOperations;
SDeferedOperation* dp = operations + numOfOperations;
dp->wrapper( dp );
static void (*wrappers)(SCleanupAction*)[] = {
cleanupWrapper_void_ptr_ptr,
cleanupWrapper_void_ptr_bool,
cleanupWrapper_void_ptr,
cleanupWrapper_int_int,
cleanupWrapper_void_void,
};
void cleanupPush_void_ptr_ptr( bool failOnly, void* func, void* arg1, void* arg2 ) {
assert( expList->numCleanupAction < expList->maxCleanupAction );
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction++;
ac->wrapper = 0;
ac->failOnly = failOnly;
ac->func = func;
ac->arg1.Ptr = arg1;
ac->arg2.Ptr = arg2;
}
void cleanupPush_void_ptr_bool( bool failOnly, void* func, void* arg1, bool arg2 ) {
assert( expList->numCleanupAction < expList->maxCleanupAction );
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction++;
ac->wrapper = 1;
ac->failOnly = failOnly;
ac->func = func;
ac->arg1.Ptr = arg1;
ac->arg2.Bool = arg2;
}
void cleanupPush_void_ptr( bool failOnly, void* func, void* arg ) {
assert( expList->numCleanupAction < expList->maxCleanupAction );
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction++;
ac->wrapper = 2;
ac->failOnly = failOnly;
ac->func = func;
ac->arg1.Ptr = arg1;
}
void cleanupPush_int_int( bool failOnly, void* func, int arg ) {
assert( expList->numCleanupAction < expList->maxCleanupAction );
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction++;
ac->wrapper = 3;
ac->failOnly = failOnly;
ac->func = func;
ac->arg1.Int = arg;
}
void cleanupPush_void( bool failOnly, void* func ) {
assert( expList->numCleanupAction < expList->maxCleanupAction );
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction++;
ac->wrapper = 4;
ac->failOnly = failOnly;
ac->func = func;
}
int32 cleanupGetActionCount() {
return expList->numCleanupAction;
}
void cleanupExecute( int32_t anchor, bool failed ) {
while( expList->numCleanupAction > anchor ) {
--expList->numCleanupAction;
SCleanupAction *ac = expList->cleanupActions + expList->numCleanupAction;
if( failed || !(ac->failOnly) )
ac->wrapper( ac );
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册