Skip to content

Commit d9b041e

Browse files
committed
assert: add ASSERT_WITH_CLEANUP
Now that we safely assert and return, we may need to be in a place where we need to unlock mutexes or cleanup resources. Provide `ASSERT_WITH_CLEANUP` that permits for this behavior by taking a block.
1 parent e32db9f commit d9b041e

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/util/assert_safe.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
# define GIT_ASSERT_WITH_RETVAL(expr, fail) assert(expr)
2626
# define GIT_ASSERT_ARG_WITH_RETVAL(expr, fail) assert(expr)
27+
28+
# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) assert(expr)
2729
#else
2830

2931
/** Internal consistency check to stop the function. */
@@ -53,6 +55,20 @@
5355
} \
5456
} while(0)
5557

58+
/**
59+
* Go to to the given label on assertion failures; useful when you have
60+
* taken a lock or otherwise need to release a resource.
61+
*/
62+
# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) \
63+
GIT_ASSERT__WITH_CLEANUP(expr, GIT_ERROR_INTERNAL, "unrecoverable internal error", cleanup)
64+
65+
# define GIT_ASSERT__WITH_CLEANUP(expr, code, msg, cleanup) do { \
66+
if (!(expr)) { \
67+
git_error_set(code, "%s: '%s'", msg, #expr); \
68+
cleanup; \
69+
} \
70+
} while(0)
71+
5672
#endif /* GIT_ASSERT_HARD */
5773

5874
#endif

tests/util/assert.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ static const char *bad_returns_string(void)
3636
return hello_world;
3737
}
3838

39+
static int has_cleanup(void)
40+
{
41+
int error = 42;
42+
43+
GIT_ASSERT_WITH_CLEANUP(1 + 1 == 3, {
44+
error = 99;
45+
goto foobar;
46+
});
47+
48+
return 0;
49+
50+
foobar:
51+
return error;
52+
}
53+
3954
void test_assert__argument(void)
4055
{
4156
cl_git_fail(dummy_fn(NULL));
@@ -92,3 +107,11 @@ void test_assert__internal(void)
92107
cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass);
93108
cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message);
94109
}
110+
111+
void test_assert__with_cleanup(void)
112+
{
113+
cl_git_fail_with(99, has_cleanup());
114+
cl_assert(git_error_last());
115+
cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass);
116+
cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message);
117+
}

0 commit comments

Comments
 (0)