|
41 | 41 | } \ |
42 | 42 | } while(0) |
43 | 43 |
|
| 44 | +/** |
| 45 | + * Thread safe assertions; you cannot use `cl_git_report_failure` from a |
| 46 | + * child thread since it will try to `longjmp` to abort and "the effect of |
| 47 | + * a call to longjmp() where initialization of the jmp_buf structure was |
| 48 | + * not performed in the calling thread is undefined." |
| 49 | + * |
| 50 | + * Instead, callers can provide a clar thread error context to a thread, |
| 51 | + * which will populate and return it on failure. Callers can check the |
| 52 | + * status with `cl_git_thread_check`. |
| 53 | + */ |
| 54 | +typedef struct { |
| 55 | + int error; |
| 56 | + const char *file; |
| 57 | + int line; |
| 58 | + const char *expr; |
| 59 | + char error_msg[4096]; |
| 60 | +} cl_git_thread_err; |
| 61 | + |
| 62 | +#define cl_git_thread_pass(threaderr, expr) cl_git_thread_pass_(threaderr, (expr), __FILE__, __LINE__) |
| 63 | + |
| 64 | +#define cl_git_thread_pass_(__threaderr, __expr, __file, __line) do { \ |
| 65 | + giterr_clear(); \ |
| 66 | + if ((((cl_git_thread_err *)__threaderr)->error = (__expr)) != 0) { \ |
| 67 | + const git_error *_last = giterr_last(); \ |
| 68 | + ((cl_git_thread_err *)__threaderr)->file = __file; \ |
| 69 | + ((cl_git_thread_err *)__threaderr)->line = __line; \ |
| 70 | + ((cl_git_thread_err *)__threaderr)->expr = "Function call failed: " #__expr; \ |
| 71 | + p_snprintf(((cl_git_thread_err *)__threaderr)->error_msg, 4096, "thread 0x%" PRIxZ " - error %d - %s", \ |
| 72 | + git_thread_currentid(), ((cl_git_thread_err *)__threaderr)->error, \ |
| 73 | + _last ? _last->message : "<no message>"); \ |
| 74 | + git_thread_exit(__threaderr); \ |
| 75 | + } \ |
| 76 | + } while (0) |
| 77 | + |
| 78 | +static void cl_git_thread_check(void *data) |
| 79 | +{ |
| 80 | + cl_git_thread_err *threaderr = (cl_git_thread_err *)data; |
| 81 | + if (threaderr->error != 0) |
| 82 | + clar__assert(0, threaderr->file, threaderr->line, threaderr->expr, threaderr->error_msg, 1); |
| 83 | +} |
| 84 | + |
44 | 85 | void cl_git_report_failure(int, const char *, int, const char *); |
45 | 86 |
|
46 | 87 | #define cl_assert_at_line(expr,file,line) \ |
|
0 commit comments