Commit d9b041e6 by Edward Thomson

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.
parent e32db9f2
......@@ -24,6 +24,8 @@
# define GIT_ASSERT_WITH_RETVAL(expr, fail) assert(expr)
# define GIT_ASSERT_ARG_WITH_RETVAL(expr, fail) assert(expr)
# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) assert(expr)
#else
/** Internal consistency check to stop the function. */
......@@ -53,6 +55,20 @@
} \
} while(0)
/**
* Go to to the given label on assertion failures; useful when you have
* taken a lock or otherwise need to release a resource.
*/
# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) \
GIT_ASSERT__WITH_CLEANUP(expr, GIT_ERROR_INTERNAL, "unrecoverable internal error", cleanup)
# define GIT_ASSERT__WITH_CLEANUP(expr, code, msg, cleanup) do { \
if (!(expr)) { \
git_error_set(code, "%s: '%s'", msg, #expr); \
cleanup; \
} \
} while(0)
#endif /* GIT_ASSERT_HARD */
#endif
......@@ -36,6 +36,21 @@ static const char *bad_returns_string(void)
return hello_world;
}
static int has_cleanup(void)
{
int error = 42;
GIT_ASSERT_WITH_CLEANUP(1 + 1 == 3, {
error = 99;
goto foobar;
});
return 0;
foobar:
return error;
}
void test_assert__argument(void)
{
cl_git_fail(dummy_fn(NULL));
......@@ -92,3 +107,11 @@ void test_assert__internal(void)
cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass);
cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message);
}
void test_assert__with_cleanup(void)
{
cl_git_fail_with(99, has_cleanup());
cl_assert(git_error_last());
cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass);
cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment