exception

This commit is contained in:
Shengliang Guan 2022-02-28 09:50:30 +08:00
parent 0fae01c975
commit a6b327fb69
2 changed files with 158 additions and 169 deletions

View File

@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TD_UTIL_EXCEPTION_H #ifndef _TD_UTIL_EXCEPTION_H_
#define _TD_UTIL_EXCEPTION_H #define _TD_UTIL_EXCEPTION_H_
#include "os.h" #include "os.h"
@ -49,7 +49,6 @@ typedef struct SCleanupAction {
} arg1, arg2; } arg1, arg2;
} SCleanupAction; } SCleanupAction;
/* /*
* exception hander registration * exception hander registration
*/ */
@ -77,8 +76,10 @@ void cleanupExecuteTo( int32_t anchor, bool failed );
void cleanupExecute(SExceptionNode* node, bool failed); void cleanupExecute(SExceptionNode* node, bool failed);
bool cleanupExceedLimit(); 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_PTR(failOnly, func, arg1, arg2) \
#define CLEANUP_PUSH_VOID_PTR_BOOL( failOnly, func, arg1, arg2 ) cleanupPush_void_ptr_bool( (failOnly), (void*)(func), (void*)(arg1), (bool)(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_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_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_VOID(failOnly, func) cleanupPush_void((failOnly), (void*)(func))
@ -98,7 +99,8 @@ void exceptionPushNode( SExceptionNode* node );
int32_t exceptionPopNode(); int32_t exceptionPopNode();
void exceptionThrow(int32_t code); void exceptionThrow(int32_t code);
#define TRY(maxCleanupActions) do { \ #define TRY(maxCleanupActions) \
do { \
SExceptionNode exceptionNode = {0}; \ SExceptionNode exceptionNode = {0}; \
SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \ SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \
exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \ exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \
@ -107,12 +109,16 @@ void exceptionThrow( int32_t code );
int caughtException = setjmp(exceptionNode.jb); \ int caughtException = setjmp(exceptionNode.jb); \
if (caughtException == 0) if (caughtException == 0)
#define CATCH( code ) int32_t code = exceptionPopNode(); \ #define CATCH(code) \
int32_t code = exceptionPopNode(); \
if (caughtException == 1) 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 THROW(x) exceptionThrow((x))
#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1)) #define CAUGHT_EXCEPTION() ((bool)(caughtException == 1))
@ -122,4 +128,4 @@ void exceptionThrow( int32_t code );
} }
#endif #endif
#endif /*_TD_UTIL_EXCEPTION_H*/ #endif /*_TD_UTIL_EXCEPTION_H_*/

View File

@ -13,7 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "os.h" #define _DEFAULT_SOURCE
#include "exception.h" #include "exception.h"
static threadlocal SExceptionNode* expList; static threadlocal SExceptionNode* expList;
@ -34,8 +34,6 @@ void exceptionThrow( int32_t code ) {
longjmp(expList->jb, 1); longjmp(expList->jb, 1);
} }
static void cleanupWrapper_void_ptr_ptr(SCleanupAction* ca) { static void cleanupWrapper_void_ptr_ptr(SCleanupAction* ca) {
void (*func)(void*, void*) = ca->func; void (*func)(void*, void*) = ca->func;
func(ca->arg1.Ptr, ca->arg2.Ptr); func(ca->arg1.Ptr, ca->arg2.Ptr);
@ -52,7 +50,7 @@ static void cleanupWrapper_void_ptr( SCleanupAction* ca ) {
} }
static void cleanupWrapper_int_int(SCleanupAction* ca) { static void cleanupWrapper_int_int(SCleanupAction* ca) {
int (*func)( int ) = ca->func; int32_t (*func)(int32_t) = ca->func;
func(ca->arg1.Int); func(ca->arg1.Int);
} }
@ -62,21 +60,16 @@ static void cleanupWrapper_void( SCleanupAction* ca ) {
} }
static void cleanupWrapper_int_ptr(SCleanupAction* ca) { static void cleanupWrapper_int_ptr(SCleanupAction* ca) {
int (*func)( void* ) = ca->func; int32_t (*func)(void*) = ca->func;
func(ca->arg1.Ptr); func(ca->arg1.Ptr);
} }
typedef void (*wrapper)(SCleanupAction*); typedef void (*wrapper)(SCleanupAction*);
static wrapper wrappers[] = { static wrapper wrappers[] = {
cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_bool, cleanupWrapper_void_ptr,
cleanupWrapper_void_ptr_bool, cleanupWrapper_int_int, cleanupWrapper_void, cleanupWrapper_int_ptr,
cleanupWrapper_void_ptr,
cleanupWrapper_int_int,
cleanupWrapper_void,
cleanupWrapper_int_ptr,
}; };
void cleanupPush_void_ptr_ptr(bool failOnly, void* func, void* arg1, void* arg2) { void cleanupPush_void_ptr_ptr(bool failOnly, void* func, void* arg1, void* arg2) {
assert(expList->numCleanupAction < expList->maxCleanupAction); assert(expList->numCleanupAction < expList->maxCleanupAction);
@ -109,7 +102,7 @@ void cleanupPush_void_ptr( bool failOnly, void* func, void* arg ) {
ca->arg1.Ptr = arg; ca->arg1.Ptr = arg;
} }
void cleanupPush_int_int( bool failOnly, void* func, int arg ) { void cleanupPush_int_int(bool failOnly, void* func, int32_t arg) {
assert(expList->numCleanupAction < expList->maxCleanupAction); assert(expList->numCleanupAction < expList->maxCleanupAction);
SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++; SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
@ -138,11 +131,7 @@ void cleanupPush_int_ptr( bool failOnly, void* func, void* arg ) {
ca->arg1.Ptr = arg; 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) { static void doExecuteCleanup(SExceptionNode* node, int32_t anchor, bool failed) {
while (node->numCleanupAction > anchor) { while (node->numCleanupAction > anchor) {
@ -154,13 +143,7 @@ static void doExecuteCleanup( SExceptionNode* node, int32_t anchor, bool failed
} }
} }
void cleanupExecuteTo( int32_t anchor, bool failed ) { void cleanupExecuteTo(int32_t anchor, bool failed) { doExecuteCleanup(expList, anchor, failed); }
doExecuteCleanup( expList, anchor, failed );
}
void cleanupExecute( SExceptionNode* node, bool failed ) { void cleanupExecute(SExceptionNode* node, bool failed) { doExecuteCleanup(node, 0, failed); }
doExecuteCleanup( node, 0, failed ); bool cleanupExceedLimit() { return expList->numCleanupAction >= expList->maxCleanupAction; }
}
bool cleanupExceedLimit() {
return expList->numCleanupAction >= expList->maxCleanupAction;
}