From 0f372e949a554b06210bca5a09fff3264ea4be1c Mon Sep 17 00:00:00 2001 From: xuxuepeng Date: Thu, 30 Nov 2023 07:42:18 +0000 Subject: [PATCH 13/13] !296 Add macro for define cleanup function * Add macro for define cleanup function --- src/auto_cleanup.h | 23 +++++++++++++------ tests/auto_cleanup_ut.cpp | 48 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/auto_cleanup.h b/src/auto_cleanup.h index 6d04372..95b6294 100644 --- a/src/auto_cleanup.h +++ b/src/auto_cleanup.h @@ -57,20 +57,29 @@ extern "C" { #define auto_cleanup_tag(name) __attribute__((__cleanup__(name##_cb))) // define all used auto tags -#define __isula_auto_free auto_cleanup_tag(free_pointer) +#define __isula_auto_free auto_cleanup_tag(free) #define __isula_auto_file auto_cleanup_tag(close_file) #define __isula_auto_dir auto_cleanup_tag(close_dir) #define __isula_auto_close auto_cleanup_tag(auto_close) #define __isula_auto_pm_unlock auto_cleanup_tag(auto_pm_unlock) #define __isula_auto_prw_unlock auto_cleanup_tag(auto_prw_unlock) -static inline void free_pointer_cb(void *ptr) -{ - void *real = *(void **)ptr; - if (real != NULL) { - free(real); +/* + * define auto cleanup callback for the type free function. + * _cleanup_func: the type free function, must be void type and + * accept one parameter with type _type *. + * _type: the type of the pointer to be cleaned up. + */ +#define define_auto_cleanup_callback(_cleanup_func, _type) \ + static inline void _cleanup_func##_cb(void *p) \ + { \ + _type *_p = *(_type **)p; \ + if (_p != NULL) { \ + _cleanup_func(_p); \ + } \ } -} + +define_auto_cleanup_callback(free, void) static inline void close_file_cb(FILE **p) { diff --git a/tests/auto_cleanup_ut.cpp b/tests/auto_cleanup_ut.cpp index 2600d56..760f0dd 100644 --- a/tests/auto_cleanup_ut.cpp +++ b/tests/auto_cleanup_ut.cpp @@ -248,4 +248,50 @@ TEST(autocleanup_testcase, test__isula_auto_close) inner_fd = open("/proc/self/cmdline", 0444); openfd = inner_fd; } -} \ No newline at end of file +} + +static bool g_test_auto_cleanup_callback_called = false; + +typedef struct foo { + int *a; + int *b; +} foo_t; + +void foo_free(foo_t *f) +{ + if (f == nullptr) { + return; + } + if (f->a != nullptr) { + free(f->a); + f->a = nullptr; + } + if (f->b != nullptr) { + free(f->b); + f->b = nullptr; + } + g_test_auto_cleanup_callback_called = true; + free(f); +} + +define_auto_cleanup_callback(foo_free, foo_t); +#define __isula_auto_foo_t auto_cleanup_tag(foo_free) + +void do_auto_cleanup_callback() +{ + __isula_auto_foo_t foo_t *f = nullptr; + + f = static_cast(malloc(sizeof(foo_t))); + f->a = static_cast(malloc(sizeof(int))); + f->b = static_cast(malloc(sizeof(int))); + *(f->a) = 1; + *(f->b) = 2; +} + +TEST(autocleanup_testcase, test_define_auto_cleanup_callback) +{ + g_test_auto_cleanup_callback_called = false; + do_auto_cleanup_callback(); + // check if the callback function is called + ASSERT_EQ(g_test_auto_cleanup_callback_called, true); +} -- 2.33.0