exception.h 4.6 KB
Newer Older
weixin_48148422's avatar
weixin_48148422 已提交
1
/*
weixin_48148422's avatar
weixin_48148422 已提交
2
 * Copyright (c) 2020 TAOS Data, Inc. <jhtao@taosdata.com>
weixin_48148422's avatar
weixin_48148422 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
Shengliang Guan 已提交
16 17
#ifndef _TD_UTIL_EXCEPTION_H
#define _TD_UTIL_EXCEPTION_H
weixin_48148422's avatar
weixin_48148422 已提交
18

S
Shengliang Guan 已提交
19
#include "os.h"
weixin_48148422's avatar
weixin_48148422 已提交
20 21 22 23 24

#ifdef __cplusplus
extern "C" {
#endif

weixin_48148422's avatar
weixin_48148422 已提交
25
/*
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 * cleanup actions
 */
typedef struct SCleanupAction {
    bool failOnly;
    uint8_t wrapper;
    uint16_t reserved;
    void* func;
    union {
        void* Ptr;
        bool Bool;
        char Char;
        int8_t Int8;
        uint8_t Uint8;
        int16_t Int16;
        uint16_t Uint16;
        int Int;
        unsigned int Uint;
        int32_t Int32;
        uint32_t Uint32;
        int64_t Int64;
        uint64_t Uint64;
        float Float;
        double Double;
    } arg1, arg2;
} SCleanupAction;

weixin_48148422's avatar
weixin_48148422 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

/*
 * 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

68 69 70 71 72
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 );
weixin_48148422's avatar
weixin_48148422 已提交
73
void cleanupPush_int_ptr        ( bool failOnly, void* func, void* arg );
74 75

int32_t cleanupGetActionCount();
weixin_48148422's avatar
weixin_48148422 已提交
76 77
void cleanupExecuteTo( int32_t anchor, bool failed );
void cleanupExecute( SExceptionNode* node, bool failed );
dengyihao's avatar
TD-816  
dengyihao 已提交
78
bool cleanupExceedLimit();
79 80 81 82 83 84

#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) )
weixin_48148422's avatar
weixin_48148422 已提交
85
#define CLEANUP_PUSH_INT_PTR( failOnly, func, arg )              cleanupPush_int_ptr( (failOnly), (void*)(func), (void*)(arg) )
86 87
#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) )
weixin_48148422's avatar
weixin_48148422 已提交
88
#define CLEANUP_PUSH_FCLOSE( failOnly, arg )                     cleanupPush_int_ptr( (failOnly), fclose, (void*)(arg) )
89

weixin_48148422's avatar
weixin_48148422 已提交
90 91
#define CLEANUP_GET_ANCHOR()          cleanupGetActionCount()
#define CLEANUP_EXECUTE_TO( anchor, failed )  cleanupExecuteTo( (anchor), (failed) )
dengyihao's avatar
TD-816  
dengyihao 已提交
92
#define CLEANUP_EXCEED_LIMIT()        cleanupExceedLimit() 
weixin_48148422's avatar
weixin_48148422 已提交
93 94 95

////////////////////////////////////////////////////////////////////////////////
// functions & macros for exception handling
weixin_48148422's avatar
weixin_48148422 已提交
96

weixin_48148422's avatar
weixin_48148422 已提交
97
void exceptionPushNode( SExceptionNode* node );
98
int32_t exceptionPopNode();
weixin_48148422's avatar
weixin_48148422 已提交
99
void exceptionThrow( int32_t code );
weixin_48148422's avatar
weixin_48148422 已提交
100

101 102
#define TRY(maxCleanupActions) do { \
    SExceptionNode exceptionNode = { 0 }; \
weixin_48148422's avatar
weixin_48148422 已提交
103 104
    SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \
    exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \
105 106 107 108
    exceptionNode.cleanupActions = cleanupActions; \
    exceptionPushNode( &exceptionNode ); \
    int caughtException = setjmp( exceptionNode.jb ); \
    if( caughtException == 0 )
weixin_48148422's avatar
weixin_48148422 已提交
109

weixin_48148422's avatar
weixin_48148422 已提交
110
#define CATCH( code ) int32_t code = exceptionPopNode(); \
weixin_48148422's avatar
weixin_48148422 已提交
111
    if( caughtException == 1 )
weixin_48148422's avatar
weixin_48148422 已提交
112

weixin_48148422's avatar
weixin_48148422 已提交
113
#define FINALLY( code ) int32_t code = exceptionPopNode();
weixin_48148422's avatar
weixin_48148422 已提交
114 115 116

#define END_TRY } while( 0 );

117
#define THROW( x )          exceptionThrow( (x) )
weixin_48148422's avatar
weixin_48148422 已提交
118 119
#define CAUGHT_EXCEPTION()  ((bool)(caughtException == 1))
#define CLEANUP_EXECUTE()   cleanupExecute( &exceptionNode, CAUGHT_EXCEPTION() )
weixin_48148422's avatar
weixin_48148422 已提交
120 121 122 123 124

#ifdef __cplusplus
}
#endif

S
Shengliang Guan 已提交
125
#endif /*_TD_UTIL_EXCEPTION_H*/