1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

fix(msg): able to create/delete msgs during notify (#3847)

Co-authored-by: wrgallo <28547933+wrgallo@users.noreply.github.com>
This commit is contained in:
wrgallo-navitas 2022-12-11 08:02:31 -03:00 committed by GitHub
parent 889634398a
commit 5cdf242a21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 5 deletions

View File

@ -338,6 +338,11 @@ menu "LVGL configuration"
bool "Enable/Disable LV_LOG_TRACE in anim module"
default y
depends on LV_USE_LOG
config LV_LOG_TRACE_MSG
bool "Enable/Disable LV_LOG_TRACE in msg module"
default y
depends on LV_USE_LOG
endmenu
menu "Asserts"

View File

@ -242,6 +242,7 @@
#define LV_LOG_TRACE_OBJ_CREATE 1
#define LV_LOG_TRACE_LAYOUT 1
#define LV_LOG_TRACE_ANIM 1
#define LV_LOG_TRACE_MSG 1
#endif /*LV_USE_LOG*/

View File

@ -724,6 +724,17 @@
#define LV_LOG_TRACE_ANIM 1
#endif
#endif
#ifndef LV_LOG_TRACE_MSG
#ifdef _LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_LOG_TRACE_MSG
#define LV_LOG_TRACE_MSG CONFIG_LV_LOG_TRACE_MSG
#else
#define LV_LOG_TRACE_MSG 0
#endif
#else
#define LV_LOG_TRACE_MSG 1
#endif
#endif
#endif /*LV_USE_LOG*/

View File

@ -26,6 +26,7 @@ typedef struct {
lv_msg_subscribe_cb_t callback;
void * user_data;
void * _priv_data; /*Internal: used only store 'obj' in lv_obj_subscribe*/
uint8_t _checked : 1; /*Internal: used to prevent multiple notifications*/
} sub_dsc_t;
/**********************
@ -39,6 +40,7 @@ static void obj_delete_event_cb(lv_event_t * e);
/**********************
* STATIC VARIABLES
**********************/
static bool restart_notify;
/**********************
* GLOBAL VARIABLES
@ -47,6 +49,11 @@ static void obj_delete_event_cb(lv_event_t * e);
/**********************
* MACROS
**********************/
#if LV_LOG_TRACE_MSG
#define MSG_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
#else
#define MSG_TRACE(...)
#endif
/**********************
* GLOBAL FUNCTIONS
@ -68,6 +75,8 @@ void * lv_msg_subscribe(lv_msg_id_t msg_id, lv_msg_subscribe_cb_t cb, void * use
s->msg_id = msg_id;
s->callback = cb;
s->user_data = user_data;
s->_checked = 1; // if subsribed during `notify`, it won't be notified immediately
restart_notify = true;
return s;
}
@ -89,6 +98,7 @@ void lv_msg_unsubscribe(void * s)
{
LV_ASSERT_NULL(s);
_lv_ll_remove(&LV_GC_ROOT(_subs_ll), s);
restart_notify = true;
lv_free(s);
}
@ -138,14 +148,48 @@ lv_msg_t * lv_event_get_msg(lv_event_t * e)
static void notify(lv_msg_t * m)
{
static unsigned int _recursion_counter = 0;
_recursion_counter++;
/*First clear all _checked flags*/
sub_dsc_t * s;
_LV_LL_READ(&LV_GC_ROOT(_subs_ll), s) {
if(s->msg_id == m->id && s->callback) {
m->user_data = s->user_data;
m->_priv_data = s->_priv_data;
s->callback(m);
if(_recursion_counter == 1) {
_LV_LL_READ(&LV_GC_ROOT(_subs_ll), s) {
s->_checked = 0;
}
}
/*Run all sub_dsc_t from the list*/
do {
restart_notify = false;
s = _lv_ll_get_head(&LV_GC_ROOT(_subs_ll));
while(s) {
/*get next element while current is surely valid*/
sub_dsc_t * next = _lv_ll_get_next(&LV_GC_ROOT(_subs_ll), s);
/*Notify only once*/
if(!s->_checked) {
/*Check if this sub_dsc_t is about this msg_id*/
if(s->msg_id == m->id && s->callback) {
// Set this flag and notify
s->_checked = 1;
m->user_data = s->user_data;
m->_priv_data = s->_priv_data;
s->callback(m);
}
}
/*restart or load next*/
if(restart_notify) {
MSG_TRACE("Start from the first sub_dsc_t again because _subs_ll may have changed");
break;
}
s = next;
}
} while(s);
_recursion_counter--;
restart_notify = (_recursion_counter > 0);
}
static void obj_notify_cb(lv_msg_t * m)