xradio-skylark-sdk icon indicating copy to clipboard operation
xradio-skylark-sdk copied to clipboard

fix bug: buttons_deinit() invalid after calling all button_destroy()

Open lovemengx opened this issue 3 years ago • 0 comments

修复问题: 修复当注册了单个或者多个 button_handle 之后,在 button_deinit() 之前又全部 button_destroy() ,那么调用 button_deinit() 会出现失效而导致资源未被正确释放的问题(即 ADC 、GPIO 的中断未被关闭和释放)。

问题原因:

  1. button_destroy() 接口的实现只是将当前的 button_handle 从 buttons_head 链表中移除。
  2. button_deinit() 接口首先会检查 button_head 链表是否为空,之后才会后续的资源释放工作。
  3. 综上所述,当所注册的所有 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;
}

lovemengx avatar Mar 26 '21 10:03 lovemengx