From 241f7a2239482f74cf7f00ba668b16192976eb25 Mon Sep 17 00:00:00 2001 From: localvar Date: Mon, 27 Apr 2020 10:23:07 +0800 Subject: [PATCH] TD-153: fix bugs --- src/util/inc/exception.h | 47 ++++++++++++++++++++-------------- src/util/inc/tbuffer.h | 54 +++++++++++++++++++++++++++++++++++++++- src/util/src/exception.c | 16 +++++++++--- src/util/src/tbuffer.c | 8 +++--- 4 files changed, 97 insertions(+), 28 deletions(-) diff --git a/src/util/inc/exception.h b/src/util/inc/exception.h index 32e2fcb61b..41f01d68dd 100644 --- a/src/util/inc/exception.h +++ b/src/util/inc/exception.h @@ -52,6 +52,22 @@ typedef struct SCleanupAction { } 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; +} 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 ); @@ -59,7 +75,8 @@ void cleanupPush_int_int ( bool failOnly, void* func, int arg ); void cleanupPush_void ( bool failOnly, void* func ); int32_t cleanupGetActionCount(); -void cleanupExecute( int32_t anchor, bool failed ); +void cleanupExecuteTo( int32_t anchor, bool failed ); +void cleanupExecute( SExceptionNode* node, bool failed ); #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) ) @@ -69,20 +86,12 @@ void cleanupExecute( int32_t anchor, bool failed ); #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) ) +#define CLEANUP_GET_ANCHOR() cleanupGetActionCount() +#define CLEANUP_EXECUTE_TO( anchor, failed ) cleanupExecuteTo( (anchor), (failed) ) -/* - * exception hander registration - */ -typedef struct SExceptionNode { - struct SExceptionNode* prev; - jmp_buf jb; - int32_t code; - int32_t maxCleanupAction; - int32_t numCleanupAction; - SCleanupAction* cleanupActions; -} SExceptionNode; + +//////////////////////////////////////////////////////////////////////////////// +// functions & macros for exception handling void exceptionPushNode( SExceptionNode* node ); int32_t exceptionPopNode(); @@ -90,23 +99,23 @@ void exceptionThrow( int code ); #define TRY(maxCleanupActions) do { \ SExceptionNode exceptionNode = { 0 }; \ - SDeferedOperation cleanupActions[maxCleanupActions > 0 ? maxCleanupActions : 1]; \ - exceptionNode.maxCleanupAction = maxCleanupActions > 0 ? maxDefered : 1; \ + SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \ + exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 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( caughtEexception == 1 ) + if( caughtException == 1 ) #define FINALLY( code ) int code = exceptionPopNode(); #define END_TRY } while( 0 ); #define THROW( x ) exceptionThrow( (x) ) -#define CAUGHT_EXCEPTION() ((bool)(caughtEexception == 1)) +#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1)) +#define CLEANUP_EXECUTE() cleanupExecute( &exceptionNode, CAUGHT_EXCEPTION() ) #ifdef __cplusplus } diff --git a/src/util/inc/tbuffer.h b/src/util/inc/tbuffer.h index 103b3710cf..8f3f7f777e 100644 --- a/src/util/inc/tbuffer.h +++ b/src/util/inc/tbuffer.h @@ -23,6 +23,58 @@ extern "C" { #endif +//////////////////////////////////////////////////////////////////////////////// +// usage example +/* +#include +#include "exception.h" + +int main( int argc, char** argv ) { + SBufferWriter bw = tbufInitWriter( NULL, false ); + + TRY( 1 ) { + //--------------------- write ------------------------ + // reserve 1024 bytes for the buffer to improve performance + tbufEnsureCapacity( &bw, 1024 ); + + // reserve space for the interger count + size_t pos = tbufReserve( &bw, sizeof(int32_t) ); + // write 5 integers to the buffer + for( int i = 0; i < 5; i++) { + tbufWriteInt32( &bw, i ); + } + // write the integer count to buffer at reserved position + tbufWriteInt32At( &bw, pos, 5 ); + + // write a string to the buffer + tbufWriteString( &bw, "this is a string.\n" ); + // acquire the result and close the write buffer + size_t size = tbufTell( &bw ); + char* data = tbufGetData( &bw, false ); + + //------------------------ read ----------------------- + SBufferReader br = tbufInitReader( data, size, false ); + // read & print out all integers + int32_t count = tbufReadInt32( &br ); + for( int i = 0; i < count; i++ ) { + printf( "%d\n", tbufReadInt32(&br) ); + } + // read & print out a string + puts( tbufReadString(&br, NULL) ); + // try read another integer, this result in an error as there no this integer + tbufReadInt32( &br ); + printf( "you should not see this message.\n" ); + } CATCH( code ) { + printf( "exception code is: %d, you will see this message after print out 5 integers and a string.\n", code ); + // throw it again and the exception will be caught in main + THROW( code ); + } END_TRY + + tbufCloseWriter( &bw ); + return 0; +} +*/ + typedef struct { bool endian; const char* data; @@ -51,7 +103,7 @@ typedef struct { size_t tbufSkip( SBufferReader* buf, size_t size ); -char* tbufRead( SBufferReader* buf, size_t size ); +const char* tbufRead( SBufferReader* buf, size_t size ); void tbufReadToBuffer( SBufferReader* buf, void* dst, size_t size ); const char* tbufReadString( SBufferReader* buf, size_t* len ); size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size ); diff --git a/src/util/src/exception.c b/src/util/src/exception.c index 27cf6fbcd6..7f8f91c784 100644 --- a/src/util/src/exception.c +++ b/src/util/src/exception.c @@ -114,11 +114,19 @@ int32_t cleanupGetActionCount() { } -void cleanupExecute( int32_t anchor, bool failed ) { - while( expList->numCleanupAction > anchor ) { - --expList->numCleanupAction; - SCleanupAction *ca = expList->cleanupActions + 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 ); } } + +void cleanupExecuteTo( int32_t anchor, bool failed ) { + doExecuteCleanup( expList, anchor, failed ); +} + +void cleanupExecute( SExceptionNode* node, bool failed ) { + doExecuteCleanup( node, 0, failed ); +} \ No newline at end of file diff --git a/src/util/src/tbuffer.c b/src/util/src/tbuffer.c index b2ded0203e..3b4cc74cc3 100644 --- a/src/util/src/tbuffer.c +++ b/src/util/src/tbuffer.c @@ -33,8 +33,8 @@ size_t tbufSkip(SBufferReader* buf, size_t size) { return old; } -char* tbufRead( SBufferReader* buf, size_t size ) { - char* ret = buf->data + buf->pos; +const char* tbufRead( SBufferReader* buf, size_t size ) { + const char* ret = buf->data + buf->pos; tbufSkip( buf, size ); return ret; } @@ -55,7 +55,7 @@ static size_t tbufReadLength( SBufferReader* buf ) { const char* tbufReadString( SBufferReader* buf, size_t* len ) { size_t l = tbufReadLength( buf ); - char* ret = buf->data + buf->pos; + const char* ret = buf->data + buf->pos; tbufSkip( buf, l + 1 ); if( ret[l] != 0 ) { THROW( TSDB_CODE_MEMORY_CORRUPTED ); @@ -80,7 +80,7 @@ size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size ) { const char* tbufReadBinary( SBufferReader* buf, size_t *len ) { size_t l = tbufReadLength( buf ); - char* ret = buf->data + buf->pos; + const char* ret = buf->data + buf->pos; tbufSkip( buf, l ); if( len != NULL ) { *len = l; -- GitLab