texception.h 4.7 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
 * cleanup actions
 */
typedef struct SCleanupAction {
S
Shengliang Guan 已提交
29 30 31 32 33
  bool     failOnly;
  uint8_t  wrapper;
  uint16_t reserved;
  void*    func;
  union {
S
Shengliang Guan 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
    void*    Ptr;
    bool     Bool;
    char     Char;
    int8_t   Int8;
    uint8_t  Uint8;
    int16_t  Int16;
    uint16_t Uint16;
    int32_t  Int;
    uint32_t Uint;
    int32_t  Int32;
    uint32_t Uint32;
    int64_t  Int64;
    uint64_t Uint64;
    float    Float;
    double   Double;
S
Shengliang Guan 已提交
49
  } arg1, arg2;
50 51
} SCleanupAction;

weixin_48148422's avatar
weixin_48148422 已提交
52 53 54 55
/*
 * exception hander registration
 */
typedef struct SExceptionNode {
S
Shengliang Guan 已提交
56 57 58 59 60 61
  struct SExceptionNode* prev;
  jmp_buf                jb;
  int32_t                code;
  int32_t                maxCleanupAction;
  int32_t                numCleanupAction;
  SCleanupAction*        cleanupActions;
weixin_48148422's avatar
weixin_48148422 已提交
62 63 64 65
} SExceptionNode;

// functions & macros for auto-cleanup

S
Shengliang Guan 已提交
66 67 68
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);
S
Shengliang Guan 已提交
69
void cleanupPush_int_int(bool failOnly, void* func, int32_t arg);
S
Shengliang Guan 已提交
70 71
void cleanupPush_void(bool failOnly, void* func);
void cleanupPush_int_ptr(bool failOnly, void* func, void* arg);
72 73

int32_t cleanupGetActionCount();
S
Shengliang Guan 已提交
74 75 76 77 78 79 80 81 82
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(failOnly, func, arg) cleanupPush_void_ptr((failOnly), (void*)(func), (void*)(arg))
S
Shengliang Guan 已提交
83
#define CLEANUP_PUSH_INT_INT(failOnly, func, arg)  cleanupPush_void_ptr((failOnly), (void*)(func), (int32_t)(arg))
S
Shengliang Guan 已提交
84 85 86
#define CLEANUP_PUSH_VOID(failOnly, func)          cleanupPush_void((failOnly), (void*)(func))
#define CLEANUP_PUSH_INT_PTR(failOnly, func, arg)  cleanupPush_int_ptr((failOnly), (void*)(func), (void*)(arg))
#define CLEANUP_PUSH_FREE(failOnly, arg)           cleanupPush_void_ptr((failOnly), free, (void*)(arg))
S
Shengliang Guan 已提交
87
#define CLEANUP_PUSH_CLOSE(failOnly, arg)          cleanupPush_int_int((failOnly), close, (int32_t)(arg))
S
Shengliang Guan 已提交
88 89 90 91 92
#define CLEANUP_PUSH_FCLOSE(failOnly, arg)         cleanupPush_int_ptr((failOnly), fclose, (void*)(arg))

#define CLEANUP_GET_ANCHOR()               cleanupGetActionCount()
#define CLEANUP_EXECUTE_TO(anchor, failed) cleanupExecuteTo((anchor), (failed))
#define CLEANUP_EXCEED_LIMIT()             cleanupExceedLimit()
weixin_48148422's avatar
weixin_48148422 已提交
93 94

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

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

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

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

S
Shengliang Guan 已提交
114
#define FINALLY(code) int32_t code = exceptionPopNode();
weixin_48148422's avatar
weixin_48148422 已提交
115

S
Shengliang Guan 已提交
116 117 118 119
#define END_TRY \
  }             \
  while (0)     \
    ;
weixin_48148422's avatar
weixin_48148422 已提交
120

S
Shengliang Guan 已提交
121 122 123
#define THROW(x)           exceptionThrow((x))
#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1))
#define CLEANUP_EXECUTE()  cleanupExecute(&exceptionNode, CAUGHT_EXCEPTION())
weixin_48148422's avatar
weixin_48148422 已提交
124 125 126 127 128

#ifdef __cplusplus
}
#endif

S
Shengliang Guan 已提交
129
#endif /*_TD_UTIL_EXCEPTION_H_*/