texception.c 4.4 KB
Newer Older
S
TD-4088  
Shengliang Guan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * 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
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "texception.h"
weixin_48148422's avatar
weixin_48148422 已提交
18

S
Shuduo Sang 已提交
19
static threadlocal SExceptionNode* expList;
weixin_48148422's avatar
weixin_48148422 已提交
20

S
Shengliang Guan 已提交
21 22 23
void exceptionPushNode(SExceptionNode* node) {
  node->prev = expList;
  expList = node;
weixin_48148422's avatar
weixin_48148422 已提交
24 25
}

26
int32_t exceptionPopNode() {
S
Shengliang Guan 已提交
27 28 29
  SExceptionNode* node = expList;
  expList = node->prev;
  return node->code;
weixin_48148422's avatar
weixin_48148422 已提交
30 31
}

S
Shengliang Guan 已提交
32 33 34
void exceptionThrow(int32_t code) {
  expList->code = code;
  longjmp(expList->jb, 1);
weixin_48148422's avatar
weixin_48148422 已提交
35
}
weixin_48148422's avatar
weixin_48148422 已提交
36

S
Shengliang Guan 已提交
37 38 39
static void cleanupWrapper_void_ptr_ptr(SCleanupAction* ca) {
  void (*func)(void*, void*) = ca->func;
  func(ca->arg1.Ptr, ca->arg2.Ptr);
40 41
}

S
Shengliang Guan 已提交
42 43 44
static void cleanupWrapper_void_ptr_bool(SCleanupAction* ca) {
  void (*func)(void*, bool) = ca->func;
  func(ca->arg1.Ptr, ca->arg2.Bool);
weixin_48148422's avatar
weixin_48148422 已提交
45 46
}

S
Shengliang Guan 已提交
47 48 49
static void cleanupWrapper_void_ptr(SCleanupAction* ca) {
  void (*func)(void*) = ca->func;
  func(ca->arg1.Ptr);
weixin_48148422's avatar
weixin_48148422 已提交
50 51
}

S
Shengliang Guan 已提交
52 53 54
static void cleanupWrapper_int_int(SCleanupAction* ca) {
  int32_t (*func)(int32_t) = ca->func;
  func(ca->arg1.Int);
55 56
}

S
Shengliang Guan 已提交
57 58 59
static void cleanupWrapper_void(SCleanupAction* ca) {
  void (*func)() = ca->func;
  func();
weixin_48148422's avatar
weixin_48148422 已提交
60 61
}

S
Shengliang Guan 已提交
62 63 64
static void cleanupWrapper_int_ptr(SCleanupAction* ca) {
  int32_t (*func)(void*) = ca->func;
  func(ca->arg1.Ptr);
weixin_48148422's avatar
weixin_48148422 已提交
65 66
}

weixin_48148422's avatar
weixin_48148422 已提交
67 68
typedef void (*wrapper)(SCleanupAction*);
static wrapper wrappers[] = {
S
Shengliang Guan 已提交
69 70
    cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_bool, cleanupWrapper_void_ptr,
    cleanupWrapper_int_int,      cleanupWrapper_void,          cleanupWrapper_int_ptr,
71 72
};

S
Shengliang Guan 已提交
73 74
void cleanupPush_void_ptr_ptr(bool failOnly, void* func, void* arg1, void* arg2) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
75

S
Shengliang Guan 已提交
76 77 78 79 80 81
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 0;
  ca->failOnly = failOnly;
  ca->func = func;
  ca->arg1.Ptr = arg1;
  ca->arg2.Ptr = arg2;
82 83
}

S
Shengliang Guan 已提交
84 85
void cleanupPush_void_ptr_bool(bool failOnly, void* func, void* arg1, bool arg2) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
86

S
Shengliang Guan 已提交
87 88 89 90 91 92
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 1;
  ca->failOnly = failOnly;
  ca->func = func;
  ca->arg1.Ptr = arg1;
  ca->arg2.Bool = arg2;
93 94
}

S
Shengliang Guan 已提交
95 96
void cleanupPush_void_ptr(bool failOnly, void* func, void* arg) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
97

S
Shengliang Guan 已提交
98 99 100 101 102
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 2;
  ca->failOnly = failOnly;
  ca->func = func;
  ca->arg1.Ptr = arg;
103 104
}

S
Shengliang Guan 已提交
105 106
void cleanupPush_int_int(bool failOnly, void* func, int32_t arg) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
107

S
Shengliang Guan 已提交
108 109 110 111 112
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 3;
  ca->failOnly = failOnly;
  ca->func = func;
  ca->arg1.Int = arg;
113 114
}

S
Shengliang Guan 已提交
115 116
void cleanupPush_void(bool failOnly, void* func) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
117

S
Shengliang Guan 已提交
118 119 120 121
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 4;
  ca->failOnly = failOnly;
  ca->func = func;
122 123
}

S
Shengliang Guan 已提交
124 125
void cleanupPush_int_ptr(bool failOnly, void* func, void* arg) {
  assert(expList->numCleanupAction < expList->maxCleanupAction);
weixin_48148422's avatar
weixin_48148422 已提交
126

S
Shengliang Guan 已提交
127 128 129 130 131
  SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
  ca->wrapper = 5;
  ca->failOnly = failOnly;
  ca->func = func;
  ca->arg1.Ptr = arg;
weixin_48148422's avatar
weixin_48148422 已提交
132
}
133

S
Shengliang Guan 已提交
134
int32_t cleanupGetActionCount() { return expList->numCleanupAction; }
135

S
Shengliang Guan 已提交
136 137 138 139 140 141
static void doExecuteCleanup(SExceptionNode* node, int32_t anchor, bool failed) {
  while (node->numCleanupAction > anchor) {
    --node->numCleanupAction;
    SCleanupAction* ca = node->cleanupActions + node->numCleanupAction;
    if (failed || !(ca->failOnly)) {
      wrappers[ca->wrapper](ca);
weixin_48148422's avatar
weixin_48148422 已提交
142
    }
S
Shengliang Guan 已提交
143
  }
weixin_48148422's avatar
weixin_48148422 已提交
144
}
weixin_48148422's avatar
weixin_48148422 已提交
145

S
Shengliang Guan 已提交
146
void cleanupExecuteTo(int32_t anchor, bool failed) { doExecuteCleanup(expList, anchor, failed); }
weixin_48148422's avatar
weixin_48148422 已提交
147

S
Shengliang Guan 已提交
148 149
void cleanupExecute(SExceptionNode* node, bool failed) { doExecuteCleanup(node, 0, failed); }
bool cleanupExceedLimit() { return expList->numCleanupAction >= expList->maxCleanupAction; }