exception.c 4.6 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
Shuduo Sang 已提交
16
#include "os.h"
weixin_48148422's avatar
weixin_48148422 已提交
17 18
#include "exception.h"

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

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

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

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

37 38 39


static void cleanupWrapper_void_ptr_ptr( SCleanupAction* ca ) {
weixin_48148422's avatar
weixin_48148422 已提交
40
    void (*func)( void*, void* ) = ca->func;
41 42 43 44 45 46
    func( ca->arg1.Ptr, ca->arg2.Ptr );
}

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 已提交
47 48
}

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

54 55
static void cleanupWrapper_int_int( SCleanupAction* ca ) {
    int (*func)( int ) = ca->func;
weixin_48148422's avatar
weixin_48148422 已提交
56
    func( ca->arg1.Int );
57 58
}

weixin_48148422's avatar
weixin_48148422 已提交
59
static void cleanupWrapper_void( SCleanupAction* ca ) {
60
    void (*func)() = ca->func;
weixin_48148422's avatar
weixin_48148422 已提交
61 62 63
    func();
}

weixin_48148422's avatar
weixin_48148422 已提交
64 65 66 67 68
static void cleanupWrapper_int_ptr( SCleanupAction* ca ) {
    int (*func)( void* ) = ca->func;
    func( ca->arg1.Ptr );
}

weixin_48148422's avatar
weixin_48148422 已提交
69 70
typedef void (*wrapper)(SCleanupAction*);
static wrapper wrappers[] = {
71 72 73 74
    cleanupWrapper_void_ptr_ptr,
    cleanupWrapper_void_ptr_bool,
    cleanupWrapper_void_ptr,
    cleanupWrapper_int_int,
weixin_48148422's avatar
weixin_48148422 已提交
75 76
    cleanupWrapper_void,
    cleanupWrapper_int_ptr,
77 78 79 80 81 82
};


void cleanupPush_void_ptr_ptr( bool failOnly, void* func, void* arg1, void* arg2 ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

weixin_48148422's avatar
weixin_48148422 已提交
83 84 85 86 87 88
    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 0;
    ca->failOnly = failOnly;
    ca->func = func;
    ca->arg1.Ptr = arg1;
    ca->arg2.Ptr = arg2;
89 90 91 92 93
}

void cleanupPush_void_ptr_bool( bool failOnly, void* func, void* arg1, bool arg2 ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

weixin_48148422's avatar
weixin_48148422 已提交
94 95 96 97 98 99
    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 1;
    ca->failOnly = failOnly;
    ca->func = func;
    ca->arg1.Ptr = arg1;
    ca->arg2.Bool = arg2;
100 101 102 103 104
}

void cleanupPush_void_ptr( bool failOnly, void* func, void* arg ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

weixin_48148422's avatar
weixin_48148422 已提交
105 106 107 108 109
    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 2;
    ca->failOnly = failOnly;
    ca->func = func;
    ca->arg1.Ptr = arg;
110 111 112 113 114
}

void cleanupPush_int_int( bool failOnly, void* func, int arg ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

weixin_48148422's avatar
weixin_48148422 已提交
115 116 117 118 119
    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 3;
    ca->failOnly = failOnly;
    ca->func = func;
    ca->arg1.Int = arg;
120 121 122 123 124
}

void cleanupPush_void( bool failOnly, void* func ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

weixin_48148422's avatar
weixin_48148422 已提交
125 126 127 128
    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 4;
    ca->failOnly = failOnly;
    ca->func = func;
129 130
}

weixin_48148422's avatar
weixin_48148422 已提交
131 132 133 134 135 136 137 138 139
void cleanupPush_int_ptr( bool failOnly, void* func, void* arg ) {
    assert( expList->numCleanupAction < expList->maxCleanupAction );

    SCleanupAction *ca = expList->cleanupActions + expList->numCleanupAction++;
    ca->wrapper = 5;
    ca->failOnly = failOnly;
    ca->func = func;
    ca->arg1.Ptr = arg;
}
140 141


weixin_48148422's avatar
weixin_48148422 已提交
142
int32_t cleanupGetActionCount() {
143 144 145 146
    return expList->numCleanupAction;
}


weixin_48148422's avatar
weixin_48148422 已提交
147 148 149 150
static void doExecuteCleanup( SExceptionNode* node, int32_t anchor, bool failed ) {
    while( node->numCleanupAction > anchor ) {
        --node->numCleanupAction;
        SCleanupAction *ca = node->cleanupActions + node->numCleanupAction;
weixin_48148422's avatar
weixin_48148422 已提交
151
        if( failed || !(ca->failOnly) ) {
weixin_48148422's avatar
weixin_48148422 已提交
152
            wrappers[ca->wrapper]( ca );
weixin_48148422's avatar
weixin_48148422 已提交
153
        }
weixin_48148422's avatar
weixin_48148422 已提交
154 155
    }
}
weixin_48148422's avatar
weixin_48148422 已提交
156 157 158 159 160 161 162

void cleanupExecuteTo( int32_t anchor, bool failed ) {
    doExecuteCleanup( expList, anchor, failed );
}

void cleanupExecute( SExceptionNode* node, bool failed ) {
    doExecuteCleanup( node, 0, failed );
S
Shuduo Sang 已提交
163
}
dengyihao's avatar
TD-816  
dengyihao 已提交
164 165 166
bool cleanupExceedLimit() {
  return expList->numCleanupAction >= expList->maxCleanupAction;
}