exception
This commit is contained in:
parent
0fae01c975
commit
a6b327fb69
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_UTIL_EXCEPTION_H
|
||||
#define _TD_UTIL_EXCEPTION_H
|
||||
#ifndef _TD_UTIL_EXCEPTION_H_
|
||||
#define _TD_UTIL_EXCEPTION_H_
|
||||
|
||||
#include "os.h"
|
||||
|
||||
|
@ -49,7 +49,6 @@ typedef struct SCleanupAction {
|
|||
} arg1, arg2;
|
||||
} SCleanupAction;
|
||||
|
||||
|
||||
/*
|
||||
* exception hander registration
|
||||
*/
|
||||
|
@ -77,8 +76,10 @@ 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_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))
|
||||
|
@ -98,7 +99,8 @@ void exceptionPushNode( SExceptionNode* node );
|
|||
int32_t exceptionPopNode();
|
||||
void exceptionThrow(int32_t code);
|
||||
|
||||
#define TRY(maxCleanupActions) do { \
|
||||
#define TRY(maxCleanupActions) \
|
||||
do { \
|
||||
SExceptionNode exceptionNode = {0}; \
|
||||
SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \
|
||||
exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \
|
||||
|
@ -107,12 +109,16 @@ void exceptionThrow( int32_t code );
|
|||
int caughtException = setjmp(exceptionNode.jb); \
|
||||
if (caughtException == 0)
|
||||
|
||||
#define CATCH( code ) int32_t code = exceptionPopNode(); \
|
||||
#define CATCH(code) \
|
||||
int32_t code = exceptionPopNode(); \
|
||||
if (caughtException == 1)
|
||||
|
||||
#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))
|
||||
|
@ -122,4 +128,4 @@ void exceptionThrow( int32_t code );
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_UTIL_EXCEPTION_H*/
|
||||
#endif /*_TD_UTIL_EXCEPTION_H_*/
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "exception.h"
|
||||
|
||||
static threadlocal SExceptionNode* expList;
|
||||
|
@ -34,8 +34,6 @@ void exceptionThrow( int32_t 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);
|
||||
|
@ -52,7 +50,7 @@ static void cleanupWrapper_void_ptr( 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);
|
||||
}
|
||||
|
||||
|
@ -62,21 +60,16 @@ static void cleanupWrapper_void( SCleanupAction* ca ) {
|
|||
}
|
||||
|
||||
static void cleanupWrapper_int_ptr(SCleanupAction* ca) {
|
||||
int (*func)( void* ) = ca->func;
|
||||
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);
|
||||
|
||||
|
@ -109,7 +102,7 @@ void cleanupPush_void_ptr( bool failOnly, void* func, void* 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);
|
||||
|
||||
SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
|
||||
|
@ -138,11 +131,7 @@ void cleanupPush_int_ptr( bool failOnly, void* func, void* 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) {
|
||||
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 ) {
|
||||
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; }
|
||||
|
|
Loading…
Reference in New Issue