TD-153: fix bugs
This commit is contained in:
parent
9fdf34552b
commit
241f7a2239
|
@ -52,25 +52,6 @@ typedef struct SCleanupAction {
|
||||||
} arg1, arg2;
|
} arg1, arg2;
|
||||||
} SCleanupAction;
|
} 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( int32_t anchor, 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) )
|
|
||||||
#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
|
* exception hander registration
|
||||||
|
@ -84,29 +65,57 @@ typedef struct SExceptionNode {
|
||||||
SCleanupAction* cleanupActions;
|
SCleanupAction* cleanupActions;
|
||||||
} SExceptionNode;
|
} 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 );
|
||||||
|
|
||||||
|
int32_t cleanupGetActionCount();
|
||||||
|
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) )
|
||||||
|
#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_GET_ANCHOR() cleanupGetActionCount()
|
||||||
|
#define CLEANUP_EXECUTE_TO( anchor, failed ) cleanupExecuteTo( (anchor), (failed) )
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// functions & macros for exception handling
|
||||||
|
|
||||||
void exceptionPushNode( SExceptionNode* node );
|
void exceptionPushNode( SExceptionNode* node );
|
||||||
int32_t exceptionPopNode();
|
int32_t exceptionPopNode();
|
||||||
void exceptionThrow( int code );
|
void exceptionThrow( int code );
|
||||||
|
|
||||||
#define TRY(maxCleanupActions) do { \
|
#define TRY(maxCleanupActions) do { \
|
||||||
SExceptionNode exceptionNode = { 0 }; \
|
SExceptionNode exceptionNode = { 0 }; \
|
||||||
SDeferedOperation cleanupActions[maxCleanupActions > 0 ? maxCleanupActions : 1]; \
|
SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \
|
||||||
exceptionNode.maxCleanupAction = maxCleanupActions > 0 ? maxDefered : 1; \
|
exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \
|
||||||
exceptionNode.cleanupActions = cleanupActions; \
|
exceptionNode.cleanupActions = cleanupActions; \
|
||||||
int32_t cleanupAnchor = 0; \
|
|
||||||
exceptionPushNode( &exceptionNode ); \
|
exceptionPushNode( &exceptionNode ); \
|
||||||
int caughtException = setjmp( exceptionNode.jb ); \
|
int caughtException = setjmp( exceptionNode.jb ); \
|
||||||
if( caughtException == 0 )
|
if( caughtException == 0 )
|
||||||
|
|
||||||
#define CATCH( code ) int code = exceptionPopNode(); \
|
#define CATCH( code ) int code = exceptionPopNode(); \
|
||||||
if( caughtEexception == 1 )
|
if( caughtException == 1 )
|
||||||
|
|
||||||
#define FINALLY( code ) int code = exceptionPopNode();
|
#define FINALLY( code ) int code = exceptionPopNode();
|
||||||
|
|
||||||
#define END_TRY } while( 0 );
|
#define END_TRY } while( 0 );
|
||||||
|
|
||||||
#define THROW( x ) exceptionThrow( (x) )
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,58 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// usage example
|
||||||
|
/*
|
||||||
|
#include <stdio.h>
|
||||||
|
#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 {
|
typedef struct {
|
||||||
bool endian;
|
bool endian;
|
||||||
const char* data;
|
const char* data;
|
||||||
|
@ -51,7 +103,7 @@ typedef struct {
|
||||||
|
|
||||||
size_t tbufSkip( SBufferReader* buf, size_t size );
|
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 );
|
void tbufReadToBuffer( SBufferReader* buf, void* dst, size_t size );
|
||||||
const char* tbufReadString( SBufferReader* buf, size_t* len );
|
const char* tbufReadString( SBufferReader* buf, size_t* len );
|
||||||
size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size );
|
size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size );
|
||||||
|
|
|
@ -114,11 +114,19 @@ int32_t cleanupGetActionCount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cleanupExecute( int32_t anchor, bool failed ) {
|
static void doExecuteCleanup( SExceptionNode* node, int32_t anchor, bool failed ) {
|
||||||
while( expList->numCleanupAction > anchor ) {
|
while( node->numCleanupAction > anchor ) {
|
||||||
--expList->numCleanupAction;
|
--node->numCleanupAction;
|
||||||
SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction;
|
SCleanupAction *ca = node->cleanupActions + node->numCleanupAction;
|
||||||
if( failed || !(ca->failOnly) )
|
if( failed || !(ca->failOnly) )
|
||||||
wrappers[ca->wrapper]( ca );
|
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 );
|
||||||
|
}
|
|
@ -33,8 +33,8 @@ size_t tbufSkip(SBufferReader* buf, size_t size) {
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* tbufRead( SBufferReader* buf, size_t size ) {
|
const char* tbufRead( SBufferReader* buf, size_t size ) {
|
||||||
char* ret = buf->data + buf->pos;
|
const char* ret = buf->data + buf->pos;
|
||||||
tbufSkip( buf, size );
|
tbufSkip( buf, size );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ static size_t tbufReadLength( SBufferReader* buf ) {
|
||||||
|
|
||||||
const char* tbufReadString( SBufferReader* buf, size_t* len ) {
|
const char* tbufReadString( SBufferReader* buf, size_t* len ) {
|
||||||
size_t l = tbufReadLength( buf );
|
size_t l = tbufReadLength( buf );
|
||||||
char* ret = buf->data + buf->pos;
|
const char* ret = buf->data + buf->pos;
|
||||||
tbufSkip( buf, l + 1 );
|
tbufSkip( buf, l + 1 );
|
||||||
if( ret[l] != 0 ) {
|
if( ret[l] != 0 ) {
|
||||||
THROW( TSDB_CODE_MEMORY_CORRUPTED );
|
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 ) {
|
const char* tbufReadBinary( SBufferReader* buf, size_t *len ) {
|
||||||
size_t l = tbufReadLength( buf );
|
size_t l = tbufReadLength( buf );
|
||||||
char* ret = buf->data + buf->pos;
|
const char* ret = buf->data + buf->pos;
|
||||||
tbufSkip( buf, l );
|
tbufSkip( buf, l );
|
||||||
if( len != NULL ) {
|
if( len != NULL ) {
|
||||||
*len = l;
|
*len = l;
|
||||||
|
|
Loading…
Reference in New Issue