From 3e6471eb8575e67b53e8be1ae0fb6231a3fd2956 Mon Sep 17 00:00:00 2001 From: localvar Date: Sat, 9 May 2020 11:51:40 +0800 Subject: [PATCH] enhance exception handling --- src/client/inc/tscUtil.h | 4 ++++ src/client/src/tscUtil.c | 23 +++++++++++++++++++++++ src/util/inc/exception.h | 9 ++++++--- src/util/src/exception.c | 26 +++++++++++++++++++++----- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 71c24501d1..dd32854663 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -265,6 +265,10 @@ void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp); void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows); void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()); +void* malloc_throw(size_t size); +void* calloc_throw(size_t nmemb, size_t size); +char* strdup_throw(const char* str); + #ifdef __cplusplus } #endif diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 1a01904839..864239f8fb 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -2156,3 +2156,26 @@ void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t column } } +void* malloc_throw(size_t size) { + void* p = malloc(size); + if (p == NULL) { + THROW(TSDB_CODE_CLI_OUT_OF_MEMORY); + } + return p; +} + +void* calloc_throw(size_t nmemb, size_t size) { + void* p = malloc(size); + if (p == NULL) { + THROW(TSDB_CODE_CLI_OUT_OF_MEMORY); + } + return p; +} + +char* strdup_throw(const char* str) { + char* p = strdup(str); + if (p == NULL) { + THROW(TSDB_CODE_CLI_OUT_OF_MEMORY); + } + return p; +} diff --git a/src/util/inc/exception.h b/src/util/inc/exception.h index 41f01d68dd..52cd03d830 100644 --- a/src/util/inc/exception.h +++ b/src/util/inc/exception.h @@ -73,6 +73,7 @@ void cleanupPush_void_ptr_bool ( bool failOnly, void* func, void* arg1, bool ar 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 ); @@ -83,8 +84,10 @@ void cleanupExecute( SExceptionNode* node, bool failed ); #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) ) @@ -95,7 +98,7 @@ void cleanupExecute( SExceptionNode* node, bool failed ); void exceptionPushNode( SExceptionNode* node ); int32_t exceptionPopNode(); -void exceptionThrow( int code ); +void exceptionThrow( int32_t code ); #define TRY(maxCleanupActions) do { \ SExceptionNode exceptionNode = { 0 }; \ @@ -106,10 +109,10 @@ void exceptionThrow( int code ); int caughtException = setjmp( exceptionNode.jb ); \ if( caughtException == 0 ) -#define CATCH( code ) int code = exceptionPopNode(); \ +#define CATCH( code ) int32_t code = exceptionPopNode(); \ if( caughtException == 1 ) -#define FINALLY( code ) int code = exceptionPopNode(); +#define FINALLY( code ) int32_t code = exceptionPopNode(); #define END_TRY } while( 0 ); diff --git a/src/util/src/exception.c b/src/util/src/exception.c index 7f8f91c784..3d2949c093 100644 --- a/src/util/src/exception.c +++ b/src/util/src/exception.c @@ -14,7 +14,7 @@ int32_t exceptionPopNode() { return node->code; } -void exceptionThrow( int code ) { +void exceptionThrow( int32_t code ) { expList->code = code; longjmp( expList->jb, 1 ); } @@ -38,21 +38,27 @@ static void cleanupWrapper_void_ptr( SCleanupAction* ca ) { static void cleanupWrapper_int_int( SCleanupAction* ca ) { int (*func)( int ) = ca->func; - func( (int)(intptr_t)(ca->arg1.Int) ); + func( ca->arg1.Int ); } -static void cleanupWrapper_void_void( SCleanupAction* ca ) { +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 ); +} + typedef void (*wrapper)(SCleanupAction*); static wrapper wrappers[] = { cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_bool, cleanupWrapper_void_ptr, cleanupWrapper_int_int, - cleanupWrapper_void_void, + cleanupWrapper_void, + cleanupWrapper_int_ptr, }; @@ -107,6 +113,15 @@ void cleanupPush_void( bool failOnly, void* func ) { ca->func = func; } +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; +} int32_t cleanupGetActionCount() { @@ -118,8 +133,9 @@ 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) ) + if( failed || !(ca->failOnly) ) { wrappers[ca->wrapper]( ca ); + } } } -- GitLab