Commit | Line | Data |
---|---|---|
553c4bab | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
553c4bab | 3 | * |
0235b0db | 4 | * Copyright (c) 2019 Philippe Proulx <pproulx@efficios.com> |
553c4bab PP |
5 | */ |
6 | ||
7 | #define BT_LOG_TAG "LIB/CUR-THREAD" | |
8 | #include "lib/logging.h" | |
9 | ||
4fa90f32 | 10 | #include <babeltrace2/babeltrace.h> |
553c4bab PP |
11 | #include <stdint.h> |
12 | #include <stdarg.h> | |
13 | ||
14 | #include "error.h" | |
15 | #include "common/assert.h" | |
d98421f2 | 16 | #include "lib/assert-cond.h" |
553c4bab PP |
17 | #include "lib/func-status.h" |
18 | ||
1778c2a4 PP |
19 | #define BT_ASSERT_PRE_FILE_NAME_NON_NULL(_file_name) \ |
20 | BT_ASSERT_PRE_NON_NULL("file-name", (_file_name), "File name"); | |
21 | ||
22 | #define BT_ASSERT_PRE_MSG_FMT_NON_NULL(_msg_fmt) \ | |
23 | BT_ASSERT_PRE_NON_NULL("message-format", (_msg_fmt), "Message format"); | |
24 | ||
553c4bab PP |
25 | /* |
26 | * This points to the thread's error object, or it's `NULL` if there's | |
27 | * no current error object. | |
28 | */ | |
29 | static __thread struct bt_error *thread_error; | |
30 | ||
31 | const struct bt_error *bt_current_thread_take_error(void) | |
32 | { | |
33 | struct bt_error *error = thread_error; | |
34 | ||
35 | thread_error = NULL; | |
36 | BT_LOGD("Took current thread's error object: addr=%p", | |
37 | error); | |
38 | return error; | |
39 | } | |
40 | ||
41 | void bt_current_thread_clear_error(void) | |
42 | { | |
43 | bt_error_destroy(thread_error); | |
44 | BT_LOGD("Cleared current thread's error object: addr=%p", | |
45 | thread_error); | |
46 | thread_error = NULL; | |
47 | } | |
48 | ||
49 | void bt_current_thread_move_error(const struct bt_error *error) | |
50 | { | |
d5b13b9b | 51 | BT_ASSERT_PRE_ERROR_NON_NULL(error); |
553c4bab PP |
52 | bt_current_thread_clear_error(); |
53 | thread_error = (void *) error; | |
54 | BT_LOGD("Moved error object as current thread's error: addr=%p", | |
55 | thread_error); | |
56 | } | |
57 | ||
58 | /* | |
59 | * Creates the current thread's error object if it does not already | |
60 | * exist. | |
61 | */ | |
62 | static | |
63 | int try_create_thread_error(void) | |
64 | { | |
65 | int status = BT_FUNC_STATUS_OK; | |
66 | ||
67 | if (thread_error) { | |
68 | goto end; | |
69 | } | |
70 | ||
71 | BT_LOGD_STR("Creating current thread's error object."); | |
72 | thread_error = bt_error_create(); | |
73 | if (!thread_error) { | |
74 | /* bt_error_create() logs errors */ | |
75 | status = BT_FUNC_STATUS_MEMORY_ERROR; | |
76 | goto end; | |
77 | } | |
78 | ||
79 | BT_LOGD("Created current thread's error object: addr=%p", thread_error); | |
80 | ||
81 | end: | |
82 | return status; | |
83 | } | |
84 | ||
85 | enum bt_current_thread_error_append_cause_status | |
86 | bt_current_thread_error_append_cause_from_unknown( | |
87 | const char *module_name, const char *file_name, | |
88 | uint64_t line_no, const char *msg_fmt, ...) | |
89 | { | |
90 | enum bt_current_thread_error_append_cause_status status = | |
91 | try_create_thread_error(); | |
92 | va_list args; | |
93 | ||
1778c2a4 PP |
94 | BT_ASSERT_PRE_NON_NULL("module-name", module_name, "Module name"); |
95 | BT_ASSERT_PRE_FILE_NAME_NON_NULL(file_name); | |
96 | BT_ASSERT_PRE_MSG_FMT_NON_NULL(msg_fmt); | |
c77d03eb | 97 | |
553c4bab PP |
98 | if (status) { |
99 | goto end; | |
100 | } | |
101 | ||
102 | BT_LOGD("Appending error cause to current thread's error from unknown actor: " | |
103 | "error-addr=%p", thread_error); | |
104 | va_start(args, msg_fmt); | |
105 | status = bt_error_append_cause_from_unknown(thread_error, module_name, | |
106 | file_name, line_no, msg_fmt, args); | |
107 | va_end(args); | |
108 | ||
109 | end: | |
110 | return status; | |
111 | } | |
112 | ||
113 | enum bt_current_thread_error_append_cause_status | |
114 | bt_current_thread_error_append_cause_from_component( | |
115 | bt_self_component *self_comp, const char *file_name, | |
116 | uint64_t line_no, const char *msg_fmt, ...) | |
117 | { | |
118 | enum bt_current_thread_error_append_cause_status status = | |
119 | try_create_thread_error(); | |
120 | va_list args; | |
121 | ||
d5b13b9b | 122 | BT_ASSERT_PRE_COMP_NON_NULL(self_comp); |
1778c2a4 PP |
123 | BT_ASSERT_PRE_FILE_NAME_NON_NULL(file_name); |
124 | BT_ASSERT_PRE_MSG_FMT_NON_NULL(msg_fmt); | |
c77d03eb | 125 | |
553c4bab PP |
126 | if (status) { |
127 | goto end; | |
128 | } | |
129 | ||
130 | BT_LOGD("Appending error cause to current thread's error from component: " | |
131 | "error-addr=%p", thread_error); | |
132 | va_start(args, msg_fmt); | |
133 | status = bt_error_append_cause_from_component(thread_error, self_comp, | |
134 | file_name, line_no, msg_fmt, args); | |
135 | va_end(args); | |
136 | ||
137 | end: | |
138 | return status; | |
139 | } | |
140 | ||
141 | enum bt_current_thread_error_append_cause_status | |
142 | bt_current_thread_error_append_cause_from_component_class( | |
143 | bt_self_component_class *self_comp_class, const char *file_name, | |
144 | uint64_t line_no, const char *msg_fmt, ...) | |
145 | { | |
146 | enum bt_current_thread_error_append_cause_status status = | |
147 | try_create_thread_error(); | |
148 | va_list args; | |
149 | ||
d5b13b9b | 150 | BT_ASSERT_PRE_COMP_CLS_NON_NULL(self_comp_class); |
1778c2a4 PP |
151 | BT_ASSERT_PRE_FILE_NAME_NON_NULL(file_name); |
152 | BT_ASSERT_PRE_MSG_FMT_NON_NULL(msg_fmt); | |
c77d03eb | 153 | |
553c4bab PP |
154 | if (status) { |
155 | goto end; | |
156 | } | |
157 | ||
158 | BT_LOGD("Appending error cause to current thread's error from component class actor: " | |
159 | "error-addr=%p", thread_error); | |
160 | va_start(args, msg_fmt); | |
161 | status = bt_error_append_cause_from_component_class(thread_error, | |
162 | self_comp_class, file_name, line_no, msg_fmt, args); | |
163 | va_end(args); | |
164 | ||
165 | end: | |
166 | return status; | |
167 | } | |
168 | ||
169 | enum bt_current_thread_error_append_cause_status | |
170 | bt_current_thread_error_append_cause_from_message_iterator( | |
171 | bt_self_message_iterator *self_iter, const char *file_name, | |
172 | uint64_t line_no, const char *msg_fmt, ...) | |
173 | { | |
174 | enum bt_current_thread_error_append_cause_status status = | |
175 | try_create_thread_error(); | |
176 | va_list args; | |
177 | ||
d5b13b9b | 178 | BT_ASSERT_PRE_MSG_ITER_NON_NULL(self_iter); |
1778c2a4 PP |
179 | BT_ASSERT_PRE_FILE_NAME_NON_NULL(file_name); |
180 | BT_ASSERT_PRE_MSG_FMT_NON_NULL(msg_fmt); | |
c77d03eb | 181 | |
553c4bab PP |
182 | if (status) { |
183 | goto end; | |
184 | } | |
185 | ||
186 | BT_LOGD("Appending error cause to current thread's error from message iterator actor: " | |
187 | "error-addr=%p", thread_error); | |
188 | va_start(args, msg_fmt); | |
189 | status = bt_error_append_cause_from_message_iterator(thread_error, | |
190 | self_iter, file_name, line_no, msg_fmt, args); | |
191 | va_end(args); | |
192 | ||
193 | end: | |
194 | return status; | |
195 | } |