From a6b327fb691522dbbb074da3ebf87e234561d70e Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Mon, 28 Feb 2022 09:50:30 +0800 Subject: [PATCH] exception --- include/util/exception.h | 142 ++++++++++++++------------- source/util/src/exception.c | 185 ++++++++++++++++-------------------- 2 files changed, 158 insertions(+), 169 deletions(-) diff --git a/include/util/exception.h b/include/util/exception.h index 8012e34315..4bf7d7593b 100644 --- a/include/util/exception.h +++ b/include/util/exception.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef _TD_UTIL_EXCEPTION_H -#define _TD_UTIL_EXCEPTION_H +#ifndef _TD_UTIL_EXCEPTION_H_ +#define _TD_UTIL_EXCEPTION_H_ #include "os.h" @@ -26,100 +26,106 @@ extern "C" { * 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; + 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; - /* * exception hander registration */ typedef struct SExceptionNode { - struct SExceptionNode* prev; - jmp_buf jb; - int32_t code; - int32_t maxCleanupAction; - int32_t numCleanupAction; - SCleanupAction* cleanupActions; + struct SExceptionNode* prev; + jmp_buf jb; + int32_t code; + int32_t maxCleanupAction; + int32_t numCleanupAction; + SCleanupAction* cleanupActions; } SExceptionNode; //////////////////////////////////////////////////////////////////////////////// // functions & macros for auto-cleanup -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 ); -void cleanupPush_int_ptr ( bool failOnly, void* func, void* arg ); +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); +void cleanupPush_int_ptr(bool failOnly, void* func, void* arg); int32_t cleanupGetActionCount(); -void cleanupExecuteTo( int32_t anchor, bool failed ); -void cleanupExecute( SExceptionNode* node, bool failed ); -bool cleanupExceedLimit(); +void cleanupExecuteTo(int32_t anchor, bool failed); +void cleanupExecute(SExceptionNode* node, bool failed); +bool cleanupExceedLimit(); -#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_INT_PTR( failOnly, func, arg ) cleanupPush_int_ptr( (failOnly), (void*)(func), (void*)(arg) ) -#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_PUSH_FCLOSE( failOnly, arg ) cleanupPush_int_ptr( (failOnly), fclose, (void*)(arg) ) +#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_INT_PTR(failOnly, func, arg) cleanupPush_int_ptr((failOnly), (void*)(func), (void*)(arg)) +#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_PUSH_FCLOSE(failOnly, arg) cleanupPush_int_ptr((failOnly), fclose, (void*)(arg)) -#define CLEANUP_GET_ANCHOR() cleanupGetActionCount() -#define CLEANUP_EXECUTE_TO( anchor, failed ) cleanupExecuteTo( (anchor), (failed) ) -#define CLEANUP_EXCEED_LIMIT() cleanupExceedLimit() +#define CLEANUP_GET_ANCHOR() cleanupGetActionCount() +#define CLEANUP_EXECUTE_TO(anchor, failed) cleanupExecuteTo((anchor), (failed)) +#define CLEANUP_EXCEED_LIMIT() cleanupExceedLimit() //////////////////////////////////////////////////////////////////////////////// // functions & macros for exception handling -void exceptionPushNode( SExceptionNode* node ); +void exceptionPushNode(SExceptionNode* node); int32_t exceptionPopNode(); -void exceptionThrow( int32_t code ); +void exceptionThrow(int32_t code); -#define TRY(maxCleanupActions) do { \ - SExceptionNode exceptionNode = { 0 }; \ - SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \ +#define TRY(maxCleanupActions) \ + do { \ + SExceptionNode exceptionNode = {0}; \ + SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \ exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \ - exceptionNode.cleanupActions = cleanupActions; \ - exceptionPushNode( &exceptionNode ); \ - int caughtException = setjmp( exceptionNode.jb ); \ - if( caughtException == 0 ) + exceptionNode.cleanupActions = cleanupActions; \ + exceptionPushNode(&exceptionNode); \ + int caughtException = setjmp(exceptionNode.jb); \ + if (caughtException == 0) -#define CATCH( code ) int32_t code = exceptionPopNode(); \ - if( caughtException == 1 ) +#define CATCH(code) \ + int32_t code = exceptionPopNode(); \ + if (caughtException == 1) -#define FINALLY( code ) int32_t code = exceptionPopNode(); +#define FINALLY(code) int32_t code = exceptionPopNode(); -#define END_TRY } while( 0 ); +#define END_TRY \ + } \ + while (0) \ + ; -#define THROW( x ) exceptionThrow( (x) ) -#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1)) -#define CLEANUP_EXECUTE() cleanupExecute( &exceptionNode, CAUGHT_EXCEPTION() ) +#define THROW(x) exceptionThrow((x)) +#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1)) +#define CLEANUP_EXECUTE() cleanupExecute(&exceptionNode, CAUGHT_EXCEPTION()) #ifdef __cplusplus } #endif -#endif /*_TD_UTIL_EXCEPTION_H*/ +#endif /*_TD_UTIL_EXCEPTION_H_*/ diff --git a/source/util/src/exception.c b/source/util/src/exception.c index 9740b9031b..614e50dad9 100644 --- a/source/util/src/exception.c +++ b/source/util/src/exception.c @@ -13,154 +13,137 @@ * along with this program. If not, see . */ -#include "os.h" +#define _DEFAULT_SOURCE #include "exception.h" static threadlocal SExceptionNode* expList; -void exceptionPushNode( SExceptionNode* node ) { - node->prev = expList; - expList = node; +void exceptionPushNode(SExceptionNode* node) { + node->prev = expList; + expList = node; } int32_t exceptionPopNode() { - SExceptionNode* node = expList; - expList = node->prev; - return node->code; + SExceptionNode* node = expList; + expList = node->prev; + return node->code; } -void exceptionThrow( int32_t code ) { - expList->code = code; - longjmp( expList->jb, 1 ); +void exceptionThrow(int32_t code) { + expList->code = code; + longjmp(expList->jb, 1); } - - -static void cleanupWrapper_void_ptr_ptr( SCleanupAction* ca ) { - void (*func)( void*, void* ) = ca->func; - func( ca->arg1.Ptr, ca->arg2.Ptr ); +static void cleanupWrapper_void_ptr_ptr(SCleanupAction* ca) { + void (*func)(void*, void*) = ca->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 ); +static void cleanupWrapper_void_ptr_bool(SCleanupAction* ca) { + void (*func)(void*, bool) = ca->func; + func(ca->arg1.Ptr, ca->arg2.Bool); } -static void cleanupWrapper_void_ptr( SCleanupAction* ca ) { - void (*func)( void* ) = ca->func; - func( ca->arg1.Ptr ); +static void cleanupWrapper_void_ptr(SCleanupAction* ca) { + void (*func)(void*) = ca->func; + func(ca->arg1.Ptr); } -static void cleanupWrapper_int_int( SCleanupAction* ca ) { - int (*func)( int ) = ca->func; - func( ca->arg1.Int ); +static void cleanupWrapper_int_int(SCleanupAction* ca) { + int32_t (*func)(int32_t) = ca->func; + func(ca->arg1.Int); } -static void cleanupWrapper_void( SCleanupAction* ca ) { - void (*func)() = ca->func; - func(); +static void cleanupWrapper_void(SCleanupAction* ca) { + void (*func)() = ca->func; + func(); } -static void cleanupWrapper_int_ptr( SCleanupAction* ca ) { - int (*func)( void* ) = ca->func; - func( ca->arg1.Ptr ); +static void cleanupWrapper_int_ptr(SCleanupAction* ca) { + int32_t (*func)(void*) = ca->func; + func(ca->arg1.Ptr); } typedef void (*wrapper)(SCleanupAction*); static wrapper wrappers[] = { - cleanupWrapper_void_ptr_ptr, - cleanupWrapper_void_ptr_bool, - cleanupWrapper_void_ptr, - cleanupWrapper_int_int, - cleanupWrapper_void, - cleanupWrapper_int_ptr, + cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_bool, cleanupWrapper_void_ptr, + cleanupWrapper_int_int, cleanupWrapper_void, cleanupWrapper_int_ptr, }; +void cleanupPush_void_ptr_ptr(bool failOnly, void* func, void* arg1, void* arg2) { + assert(expList->numCleanupAction < expList->maxCleanupAction); -void cleanupPush_void_ptr_ptr( bool failOnly, void* func, void* arg1, void* arg2 ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); - - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 0; - ca->failOnly = failOnly; - ca->func = func; - ca->arg1.Ptr = arg1; - ca->arg2.Ptr = arg2; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 0; + ca->failOnly = failOnly; + ca->func = func; + ca->arg1.Ptr = arg1; + ca->arg2.Ptr = arg2; } -void cleanupPush_void_ptr_bool( bool failOnly, void* func, void* arg1, bool arg2 ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); +void cleanupPush_void_ptr_bool(bool failOnly, void* func, void* arg1, bool arg2) { + assert(expList->numCleanupAction < expList->maxCleanupAction); - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 1; - ca->failOnly = failOnly; - ca->func = func; - ca->arg1.Ptr = arg1; - ca->arg2.Bool = arg2; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 1; + ca->failOnly = failOnly; + ca->func = func; + ca->arg1.Ptr = arg1; + ca->arg2.Bool = arg2; } -void cleanupPush_void_ptr( bool failOnly, void* func, void* arg ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); +void cleanupPush_void_ptr(bool failOnly, void* func, void* arg) { + assert(expList->numCleanupAction < expList->maxCleanupAction); - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 2; - ca->failOnly = failOnly; - ca->func = func; - ca->arg1.Ptr = arg; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 2; + ca->failOnly = failOnly; + ca->func = func; + ca->arg1.Ptr = arg; } -void cleanupPush_int_int( bool failOnly, void* func, int arg ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); +void cleanupPush_int_int(bool failOnly, void* func, int32_t arg) { + assert(expList->numCleanupAction < expList->maxCleanupAction); - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 3; - ca->failOnly = failOnly; - ca->func = func; - ca->arg1.Int = arg; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 3; + ca->failOnly = failOnly; + ca->func = func; + ca->arg1.Int = arg; } -void cleanupPush_void( bool failOnly, void* func ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); +void cleanupPush_void(bool failOnly, void* func) { + assert(expList->numCleanupAction < expList->maxCleanupAction); - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 4; - ca->failOnly = failOnly; - ca->func = func; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 4; + ca->failOnly = failOnly; + ca->func = func; } -void cleanupPush_int_ptr( bool failOnly, void* func, void* arg ) { - assert( expList->numCleanupAction < expList->maxCleanupAction ); +void cleanupPush_int_ptr(bool failOnly, void* func, void* arg) { + assert(expList->numCleanupAction < expList->maxCleanupAction); - SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++; - ca->wrapper = 5; - ca->failOnly = failOnly; - ca->func = func; - ca->arg1.Ptr = arg; + SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; + ca->wrapper = 5; + ca->failOnly = failOnly; + ca->func = func; + ca->arg1.Ptr = arg; } +int32_t cleanupGetActionCount() { return expList->numCleanupAction; } -int32_t cleanupGetActionCount() { - return expList->numCleanupAction; -} - - -static void doExecuteCleanup( SExceptionNode* node, int32_t anchor, bool failed ) { - while( node->numCleanupAction > anchor ) { - --node->numCleanupAction; - SCleanupAction *ca = node->cleanupActions + node->numCleanupAction; - if( failed || !(ca->failOnly) ) { - wrappers[ca->wrapper]( ca ); - } +static void doExecuteCleanup(SExceptionNode* node, int32_t anchor, bool failed) { + while (node->numCleanupAction > anchor) { + --node->numCleanupAction; + SCleanupAction* ca = node->cleanupActions + node->numCleanupAction; + if (failed || !(ca->failOnly)) { + wrappers[ca->wrapper](ca); } + } } -void cleanupExecuteTo( int32_t anchor, bool failed ) { - doExecuteCleanup( expList, anchor, failed ); -} +void cleanupExecuteTo(int32_t anchor, bool failed) { doExecuteCleanup(expList, anchor, failed); } -void cleanupExecute( SExceptionNode* node, bool failed ) { - doExecuteCleanup( node, 0, failed ); -} -bool cleanupExceedLimit() { - return expList->numCleanupAction >= expList->maxCleanupAction; -} +void cleanupExecute(SExceptionNode* node, bool failed) { doExecuteCleanup(node, 0, failed); } +bool cleanupExceedLimit() { return expList->numCleanupAction >= expList->maxCleanupAction; }