xradio-skylark-sdk
xradio-skylark-sdk copied to clipboard
fix bug: buttons_deinit() invalid after calling all button_destroy()
修复问题: 修复当注册了单个或者多个 button_handle 之后,在 button_deinit() 之前又全部 button_destroy() ,那么调用 button_deinit() 会出现失效而导致资源未被正确释放的问题(即 ADC 、GPIO 的中断未被关闭和释放)。
问题原因:
- button_destroy() 接口的实现只是将当前的 button_handle 从 buttons_head 链表中移除。
- button_deinit() 接口首先会检查 button_head 链表是否为空,之后才会后续的资源释放工作。
- 综上所述,当所注册的所有 button_handle 都调用了 button_destroy() 之后,那么 buttons_head 链表就必定为空,这就导致后续调用 button_deinit() 接口会因为该链表为空而直接 return 0, 导致后续的释放工作并未进行。
代码解释:
static int button_destroy(button_handle * handle)
{
button_obj *obj = GET_BASE(handle);
button_obj *obj_t;
if (obj == current_tiggered_obj) {
BUTTON_ERR("the button is working, can not destroy");
return -1;
}
if (list_empty(&buttons_head))
return -1;
/* delete and free the button object from buttons list head */
list_for_each_entry(obj_t, &buttons_head, node) {
if (obj_t == obj) {
list_del(&obj->node); // <---- 这个位置会将当前的 button_handle 从 buttons_head 链表中移除
free(obj);
return 0;
}
}
return 0;
}
int buttons_deinit(void)
{
button_obj *obj_t;
if (list_empty(&buttons_head)) // <----- 这里的判断语句将会成立,导致直接返回了 0
return 0;
buttons_thread_run_flag = 0;
/* release the semaphore,
* prevent the buttons thread from waiting for the semaphore all the time.
*/
if (button_impl.low_level_release_semaphore)
button_impl.low_level_release_semaphore();
/* waiting for the buttons thread delete */
while (OS_ThreadIsValid(&buttons_thread))
OS_MSleep(1);
/* delete and free all the button objects */
while (!list_empty(&buttons_head)) {
obj_t = list_first_entry(&buttons_head, button_obj, node);
list_del(&obj_t->node);
free(obj_t);
}
if (OS_TimerIsValid(&buttons_timer))
OS_TimerDelete(&buttons_timer);
if (button_impl.low_level_deinit)
button_impl.low_level_deinit();
memset(&button_impl, 0, sizeof(button_impl));
return 0;
}