From fbb65d2fe3e57f44a66cad84b525e803597395fd Mon Sep 17 00:00:00 2001 From: bjsylvia Date: Mon, 6 Nov 2023 21:55:52 +0800 Subject: [PATCH] fix(leak): fix common memory leak on lv_init (#4750) Signed-off-by: XiaoweiYan Co-authored-by: XiaoweiYan --- src/core/lv_group.c | 5 ++++ src/core/lv_group.h | 6 ++++ src/core/lv_obj_style.c | 5 ++++ src/core/lv_obj_style.h | 6 ++++ src/core/lv_refr.c | 4 +++ src/core/lv_refr.h | 5 ++++ src/draw/lv_draw.c | 17 +++++++++++ src/draw/lv_draw.h | 9 ++++++ src/draw/lv_image_decoder.c | 8 +++++ src/draw/lv_image_decoder.h | 5 ++++ src/draw/nxp/pxp/lv_draw_pxp.c | 5 ++++ src/draw/nxp/pxp/lv_draw_pxp.h | 2 ++ src/draw/nxp/vglite/lv_draw_vglite.c | 4 +++ src/draw/nxp/vglite/lv_draw_vglite.h | 2 ++ src/draw/sw/lv_draw_sw.c | 20 +++++++++++++ src/draw/sw/lv_draw_sw.h | 2 ++ src/draw/sw/lv_draw_sw_mask.c | 4 +++ src/draw/sw/lv_draw_sw_mask.h | 2 ++ src/layouts/lv_layout.c | 5 ++++ src/layouts/lv_layout.h | 2 ++ src/libs/bmp/lv_bmp.c | 11 +++++++ src/libs/bmp/lv_bmp.h | 1 + src/lv_init.c | 45 ++++++++++++++++++++++++++-- src/misc/lv_anim.c | 5 ++++ src/misc/lv_anim.h | 5 ++++ src/misc/lv_cache.c | 5 ++++ src/misc/lv_cache.h | 5 ++++ src/misc/lv_cache_builtin.c | 5 ++++ src/misc/lv_cache_builtin.h | 2 ++ src/misc/lv_fs.c | 5 ++++ src/misc/lv_fs.h | 5 ++++ src/misc/lv_timer.c | 7 +++++ src/misc/lv_timer.h | 5 ++++ 33 files changed, 221 insertions(+), 3 deletions(-) diff --git a/src/core/lv_group.c b/src/core/lv_group.c index 1b5e5c93b..218698d81 100644 --- a/src/core/lv_group.c +++ b/src/core/lv_group.c @@ -48,6 +48,11 @@ void _lv_group_init(void) _lv_ll_init(group_ll_p, sizeof(lv_group_t)); } +void _lv_group_deinit(void) +{ + _lv_ll_clear(group_ll_p); +} + lv_group_t * lv_group_create(void) { lv_group_t * group = _lv_ll_ins_head(group_ll_p); diff --git a/src/core/lv_group.h b/src/core/lv_group.h index f7404c1ec..459d9266d 100644 --- a/src/core/lv_group.h +++ b/src/core/lv_group.h @@ -97,6 +97,12 @@ typedef enum { */ void _lv_group_init(void); +/** + * Deinit. the group module + * @remarks Internal function, do not call directly. + */ +void _lv_group_deinit(void); + /** * Create a new object group * @return pointer to the new object group diff --git a/src/core/lv_obj_style.c b/src/core/lv_obj_style.c index 88241d373..a5c5038da 100644 --- a/src/core/lv_obj_style.c +++ b/src/core/lv_obj_style.c @@ -79,6 +79,11 @@ void _lv_obj_style_init(void) _lv_ll_init(style_trans_ll_p, sizeof(trans_t)); } +void _lv_obj_style_deinit(void) +{ + _lv_ll_clear(style_trans_ll_p); +} + void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector) { LV_ASSERT(obj->style_cnt < 63); diff --git a/src/core/lv_obj_style.h b/src/core/lv_obj_style.h index 477cc54d1..aff4e822f 100644 --- a/src/core/lv_obj_style.h +++ b/src/core/lv_obj_style.h @@ -75,6 +75,12 @@ typedef struct { */ void _lv_obj_style_init(void); +/** + * Deinitialize the object related style manager module. + * Called by LVGL in `lv_deinit()` + */ +void _lv_obj_style_deinit(void); + /** * Add a style to an object. * @param obj pointer to an object diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 6da6e3c8d..61526e35f 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -70,6 +70,10 @@ void _lv_refr_init(void) { } +void _lv_refr_deinit(void) +{ +} + void lv_refr_now(lv_display_t * disp) { lv_anim_refr_now(); diff --git a/src/core/lv_refr.h b/src/core/lv_refr.h index 5bc6c667f..2181824bb 100644 --- a/src/core/lv_refr.h +++ b/src/core/lv_refr.h @@ -46,6 +46,11 @@ extern "C" { */ void _lv_refr_init(void); +/** + * Deinitialize the screen refresh subsystem + */ +void _lv_refr_deinit(void); + /** * Redraw the invalidated areas now. * Normally the redrawing is periodically executed in `lv_timer_handler` but a long blocking process diff --git a/src/draw/lv_draw.c b/src/draw/lv_draw.c index 63b334036..a9fdc87f9 100644 --- a/src/draw/lv_draw.c +++ b/src/draw/lv_draw.c @@ -50,6 +50,23 @@ void lv_draw_init(void) #endif } +void lv_draw_deinit(void) +{ +#if LV_USE_OS + lv_thread_sync_delete(&_draw_info.sync); +#endif + + lv_draw_unit_t * u = _draw_info.unit_head; + while(u) { + lv_draw_unit_t * cur_unit = u; + u = u->next; + + if(cur_unit->delete_cb) cur_unit->delete_cb(cur_unit); + lv_free(cur_unit); + } + _draw_info.unit_head = NULL; +} + void * lv_draw_create_unit(size_t size) { lv_draw_unit_t * new_unit = lv_malloc(size); diff --git a/src/draw/lv_draw.h b/src/draw/lv_draw.h index 52ada8118..2d81af0ac 100644 --- a/src/draw/lv_draw.h +++ b/src/draw/lv_draw.h @@ -129,6 +129,13 @@ typedef struct _lv_draw_unit_t { * @return */ int32_t (*evaluate_cb)(struct _lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + + /** + * Called to delete draw unit. + * @param draw_unit + * @return + */ + int32_t (*delete_cb)(struct _lv_draw_unit_t * draw_unit); } lv_draw_unit_t; @@ -190,6 +197,8 @@ typedef struct { void lv_draw_init(void); +void lv_draw_deinit(void); + /** * Allocate a new draw unit with the given size and appends it to the list of draw units * @param size the size to allocate. E.g. `sizeof(my_draw_unit_t)`, diff --git a/src/draw/lv_image_decoder.c b/src/draw/lv_image_decoder.c index 21b45fd88..ca808ad70 100644 --- a/src/draw/lv_image_decoder.c +++ b/src/draw/lv_image_decoder.c @@ -74,6 +74,14 @@ void _lv_image_decoder_init(void) lv_image_decoder_set_close_cb(decoder, lv_image_decoder_built_in_close); } +/** + * Deinitialize the image decoder module + */ +void _lv_image_decoder_deinit(void) +{ + _lv_ll_clear(img_decoder_ll_p); +} + /** * Get information about an image. * Try the created image decoder one by one. Once one is able to get info that info will be used. diff --git a/src/draw/lv_image_decoder.h b/src/draw/lv_image_decoder.h index 9dab56b60..ed8475fec 100644 --- a/src/draw/lv_image_decoder.h +++ b/src/draw/lv_image_decoder.h @@ -146,6 +146,11 @@ typedef struct _lv_image_decoder_dsc_t { */ void _lv_image_decoder_init(void); +/** + * Deinitialize the image decoder module + */ +void _lv_image_decoder_deinit(void); + /** * Get information about an image. * Try the created image decoder one by one. Once one is able to get info that info will be used. diff --git a/src/draw/nxp/pxp/lv_draw_pxp.c b/src/draw/nxp/pxp/lv_draw_pxp.c index 038f587ea..bb483bee8 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp.c +++ b/src/draw/nxp/pxp/lv_draw_pxp.c @@ -83,6 +83,11 @@ void lv_draw_pxp_init(void) #endif } +void lv_draw_pxp_deinit(void) +{ + lv_pxp_deinit(); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/draw/nxp/pxp/lv_draw_pxp.h b/src/draw/nxp/pxp/lv_draw_pxp.h index 156eb68e7..31eaf2487 100644 --- a/src/draw/nxp/pxp/lv_draw_pxp.h +++ b/src/draw/nxp/pxp/lv_draw_pxp.h @@ -53,6 +53,8 @@ void lv_draw_buf_pxp_init_handlers(void); void lv_draw_pxp_init(void); +void lv_draw_pxp_deinit(void); + void lv_draw_pxp_bg_img(lv_draw_unit_t * draw_unit, const lv_draw_bg_image_dsc_t * dsc, const lv_area_t * coords); diff --git a/src/draw/nxp/vglite/lv_draw_vglite.c b/src/draw/nxp/vglite/lv_draw_vglite.c index 405457242..b2d407541 100644 --- a/src/draw/nxp/vglite/lv_draw_vglite.c +++ b/src/draw/nxp/vglite/lv_draw_vglite.c @@ -104,6 +104,10 @@ void lv_draw_vglite_init(void) #endif } +void lv_draw_vglite_deinit(void) +{ +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/draw/nxp/vglite/lv_draw_vglite.h b/src/draw/nxp/vglite/lv_draw_vglite.h index c357f982a..58a69dff0 100644 --- a/src/draw/nxp/vglite/lv_draw_vglite.h +++ b/src/draw/nxp/vglite/lv_draw_vglite.h @@ -66,6 +66,8 @@ void lv_draw_buf_vglite_init_handlers(void); void lv_draw_vglite_init(void); +void lv_draw_vglite_deinit(void); + void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); diff --git a/src/draw/sw/lv_draw_sw.c b/src/draw/sw/lv_draw_sw.c index 84fe4365d..780d7a6bc 100644 --- a/src/draw/sw/lv_draw_sw.c +++ b/src/draw/sw/lv_draw_sw.c @@ -34,6 +34,7 @@ static void execute_drawing(lv_draw_sw_unit_t * u); static int32_t lv_draw_sw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); +static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit); /********************** * STATIC VARIABLES @@ -60,6 +61,7 @@ void lv_draw_sw_init(void) lv_draw_sw_unit_t * draw_sw_unit = lv_draw_create_unit(sizeof(lv_draw_sw_unit_t)); draw_sw_unit->base_unit.dispatch_cb = lv_draw_sw_dispatch; draw_sw_unit->idx = i; + draw_sw_unit->base_unit.delete_cb = LV_USE_OS ? lv_draw_sw_delete : NULL; #if LV_USE_OS lv_thread_init(&draw_sw_unit->thread, LV_THREAD_PRIO_HIGH, render_thread_cb, 8 * 1024, draw_sw_unit); @@ -67,6 +69,24 @@ void lv_draw_sw_init(void) } } +void lv_draw_sw_deinit(void) +{ +#if LV_DRAW_SW_COMPLEX == 1 + lv_draw_sw_mask_deinit(); +#endif +} + +static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit) +{ +#if LV_USE_OS + lv_draw_sw_unit_t * draw_sw_unit = (lv_draw_sw_unit_t *) draw_unit; + return lv_thread_delete(&draw_sw_unit->thread); +#else + LV_UNUSED(draw_unit); + return 0; +#endif +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/draw/sw/lv_draw_sw.h b/src/draw/sw/lv_draw_sw.h index 97c31f6c2..ea2ca6131 100644 --- a/src/draw/sw/lv_draw_sw.h +++ b/src/draw/sw/lv_draw_sw.h @@ -53,6 +53,8 @@ typedef struct { void lv_draw_sw_init(void); +void lv_draw_sw_deinit(void); + LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); diff --git a/src/draw/sw/lv_draw_sw_mask.c b/src/draw/sw/lv_draw_sw_mask.c index 8af24e418..4242ecf79 100644 --- a/src/draw/sw/lv_draw_sw_mask.c +++ b/src/draw/sw/lv_draw_sw_mask.c @@ -82,6 +82,10 @@ void lv_draw_sw_mask_init(void) lv_mutex_init(&circle_cache_mutex); } +void lv_draw_sw_mask_deinit(void) +{ + lv_mutex_delete(&circle_cache_mutex); +} LV_ATTRIBUTE_FAST_MEM lv_draw_sw_mask_res_t lv_draw_sw_mask_apply(void * masks[], lv_opa_t * mask_buf, int32_t abs_x, int32_t abs_y, diff --git a/src/draw/sw/lv_draw_sw_mask.h b/src/draw/sw/lv_draw_sw_mask.h index 9588108ea..c7572762c 100644 --- a/src/draw/sw/lv_draw_sw_mask.h +++ b/src/draw/sw/lv_draw_sw_mask.h @@ -188,6 +188,8 @@ typedef struct _lv_draw_sw_mask_map_param_t { void lv_draw_sw_mask_init(void); +void lv_draw_sw_mask_deinit(void); + //! @cond Doxygen_Suppress /** diff --git a/src/layouts/lv_layout.c b/src/layouts/lv_layout.c index 50674ebe9..a14c1219f 100644 --- a/src/layouts/lv_layout.c +++ b/src/layouts/lv_layout.c @@ -50,6 +50,11 @@ void _lv_layout_init(void) #endif } +void _lv_layout_deinit(void) +{ + lv_free(layout_list_def); +} + uint32_t lv_layout_register(lv_layout_update_cb_t cb, void * user_data) { layout_list_def = lv_realloc(layout_list_def, (layout_cnt + 1) * sizeof(lv_layout_dsc_t)); diff --git a/src/layouts/lv_layout.h b/src/layouts/lv_layout.h index b72a5831d..8fc31109d 100644 --- a/src/layouts/lv_layout.h +++ b/src/layouts/lv_layout.h @@ -53,6 +53,8 @@ typedef enum { void _lv_layout_init(void); +void _lv_layout_deinit(void); + /** * Register a new layout * @param cb the layout update callback diff --git a/src/libs/bmp/lv_bmp.c b/src/libs/bmp/lv_bmp.c index eb86bdfa5..0781871e4 100644 --- a/src/libs/bmp/lv_bmp.c +++ b/src/libs/bmp/lv_bmp.c @@ -59,6 +59,17 @@ void lv_bmp_init(void) lv_image_decoder_set_close_cb(dec, decoder_close); } +void lv_bmp_deinit(void) +{ + lv_image_decoder_t * dec = NULL; + while((dec = lv_image_decoder_get_next(dec)) != NULL) { + if(dec->info_cb == decoder_info) { + lv_image_decoder_delete(dec); + break; + } + } +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/libs/bmp/lv_bmp.h b/src/libs/bmp/lv_bmp.h index 5577f5f65..a7dbe277b 100644 --- a/src/libs/bmp/lv_bmp.h +++ b/src/libs/bmp/lv_bmp.h @@ -28,6 +28,7 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ void lv_bmp_init(void); +void lv_bmp_deinit(void); /********************** * MACROS diff --git a/src/lv_init.c b/src/lv_init.c index f4488c87d..66b96d4e0 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -302,15 +302,54 @@ void lv_deinit(void) lv_theme_mono_deinit(); #endif + _lv_cache_builtin_deinit(); + + _lv_cache_deinit(); + + _lv_image_decoder_deinit(); + + _lv_refr_deinit(); + + _lv_obj_style_deinit(); + +#if LV_USE_DRAW_PXP + lv_draw_pxp_deinit(); +#endif + +#if LV_USE_DRAW_VGLITE + lv_draw_vglite_deinit(); +#endif + +#if LV_USE_DRAW_SW + lv_draw_sw_deinit(); +#endif + + lv_draw_deinit(); + + _lv_group_deinit(); + + _lv_anim_core_deinit(); + + _lv_layout_deinit(); + + _lv_fs_deinit(); + + _lv_timer_core_deinit(); + +#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN + lv_profiler_builtin_uninit(); +#endif + +#if LV_USE_OBJ_ID_BUILTIN + lv_objid_builtin_destroy(); +#endif + lv_mem_deinit(); #if LV_USE_LOG lv_log_register_print_cb(NULL); #endif -#if LV_USE_OBJ_ID_BUILTIN - lv_objid_builtin_destroy(); -#endif #endif lv_initialized = false; diff --git a/src/misc/lv_anim.c b/src/misc/lv_anim.c index 7c75fb734..0d11a2975 100644 --- a/src/misc/lv_anim.c +++ b/src/misc/lv_anim.c @@ -64,6 +64,11 @@ void _lv_anim_core_init(void) state.anim_run_round = false; } +void _lv_anim_core_deinit(void) +{ + lv_anim_delete_all(); +} + void lv_anim_init(lv_anim_t * a) { lv_memzero(a, sizeof(lv_anim_t)); diff --git a/src/misc/lv_anim.h b/src/misc/lv_anim.h index 6a7745133..ee92e4d04 100644 --- a/src/misc/lv_anim.h +++ b/src/misc/lv_anim.h @@ -173,6 +173,11 @@ typedef struct _lv_anim_t { */ void _lv_anim_core_init(void); +/** + * Deinit. the animation module + */ +void _lv_anim_core_deinit(void); + /** * Initialize an animation variable. * E.g.: diff --git a/src/misc/lv_cache.c b/src/misc/lv_cache.c index 5991fccae..203944ca8 100644 --- a/src/misc/lv_cache.c +++ b/src/misc/lv_cache.c @@ -42,6 +42,11 @@ void _lv_cache_init(void) lv_mutex_init(&_cache_manager.mutex); } +void _lv_cache_deinit(void) +{ + lv_mutex_delete(&_cache_manager.mutex); +} + void lv_cache_set_manager(lv_cache_manager_t * manager) { LV_ASSERT(_cache_manager.locked); diff --git a/src/misc/lv_cache.h b/src/misc/lv_cache.h index c3e259ee9..9c267afb3 100644 --- a/src/misc/lv_cache.h +++ b/src/misc/lv_cache.h @@ -152,6 +152,11 @@ typedef struct { */ void _lv_cache_init(void); +/** + * Deinitialize the cache module + */ +void _lv_cache_deinit(void); + /** * Set new cache manager * @param manager the new cache manager with callback functions set diff --git a/src/misc/lv_cache_builtin.c b/src/misc/lv_cache_builtin.c index 4b1421d0e..223da5b35 100644 --- a/src/misc/lv_cache_builtin.c +++ b/src/misc/lv_cache_builtin.c @@ -65,6 +65,11 @@ void _lv_cache_builtin_init(void) _cache_manager.empty_cb = empty_cb; } +void _lv_cache_builtin_deinit(void) +{ + _lv_ll_clear(&dsc.entry_ll); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/misc/lv_cache_builtin.h b/src/misc/lv_cache_builtin.h index 7b88cfc6d..846a9029d 100644 --- a/src/misc/lv_cache_builtin.h +++ b/src/misc/lv_cache_builtin.h @@ -34,6 +34,8 @@ typedef struct { void _lv_cache_builtin_init(void); +void _lv_cache_builtin_deinit(void); + /********************** * MACROS **********************/ diff --git a/src/misc/lv_fs.c b/src/misc/lv_fs.c index f9674afa4..3ff6357ad 100644 --- a/src/misc/lv_fs.c +++ b/src/misc/lv_fs.c @@ -45,6 +45,11 @@ void _lv_fs_init(void) _lv_ll_init(fsdrv_ll_p, sizeof(lv_fs_drv_t *)); } +void _lv_fs_deinit(void) +{ + _lv_ll_clear(fsdrv_ll_p); +} + bool lv_fs_is_ready(char letter) { lv_fs_drv_t * drv = lv_fs_get_drv(letter); diff --git a/src/misc/lv_fs.h b/src/misc/lv_fs.h index 0c824a43b..fe18dd4eb 100644 --- a/src/misc/lv_fs.h +++ b/src/misc/lv_fs.h @@ -133,6 +133,11 @@ typedef struct { */ void _lv_fs_init(void); +/** + * Deinitialize the File system interface + */ +void _lv_fs_deinit(void); + /** * Initialize a file system driver with default values. * It is used to ensure all fields have known values and not memory junk. diff --git a/src/misc/lv_timer.c b/src/misc/lv_timer.c index 29ccbbdf9..1af2785e5 100644 --- a/src/misc/lv_timer.c +++ b/src/misc/lv_timer.c @@ -242,6 +242,13 @@ void lv_timer_enable(bool en) if(en) lv_timer_handler_resume(); } +void _lv_timer_core_deinit(void) +{ + lv_timer_enable(false); + + _lv_ll_clear(timer_ll_p); +} + uint8_t lv_timer_get_idle(void) { return state.idle_last; diff --git a/src/misc/lv_timer.h b/src/misc/lv_timer.h index 9fd0a8cc7..4323d7d94 100644 --- a/src/misc/lv_timer.h +++ b/src/misc/lv_timer.h @@ -85,6 +85,11 @@ typedef struct { */ void _lv_timer_core_init(void); +/** + * Deinit the lv_timer module + */ +void _lv_timer_core_deinit(void); + //! @cond Doxygen_Suppress /**