elementary: fix potential race condition by using Eina_Future attached to the object.

I get some random segfault in elementary test suite pointing to this code. Most likely
we do not properly destroy the timer during destruction. Could be because we initiate
a delay while destruction is going on or something like that. Anyway, it is easier and
more robust to get it fixed by linking the lifetime of the timeout to the lifetime of
the widget as future allow us to do easily.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D9298
This commit is contained in:
Cedric BAIL 2019-07-11 15:53:54 -07:00 committed by Marcel Hollerbach
parent 83700fe13c
commit 477611f014
2 changed files with 19 additions and 10 deletions

View File

@ -113,15 +113,20 @@ _label_write(Evas_Object *obj)
eina_strbuf_free(strbuf);
}
static Eina_Bool
_delay_change_timer_cb(void *data)
static Eina_Value
_delay_change_timer_cb(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
efl_event_callback_call(o, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
return v;
}
static void
_delay_change_timer_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = data;
sd->delay_change_timer = NULL;
efl_event_callback_call(data, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
return ECORE_CALLBACK_CANCEL;
}
static Eina_Bool
@ -130,6 +135,7 @@ _value_set(Evas_Object *obj,
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
Eina_Future *f;
if (sd->circulate)
{
@ -146,9 +152,12 @@ _value_set(Evas_Object *obj,
if (EINA_DBL_EQ(new_val, efl_ui_range_value_get(obj))) return EINA_TRUE;
efl_ui_range_value_set(obj, new_val);
ecore_timer_del(sd->delay_change_timer);
sd->delay_change_timer = ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
_delay_change_timer_cb, obj);
if (sd->delay_change_timer) eina_future_cancel(sd->delay_change_timer);
f = efl_loop_timeout(efl_loop_get(obj), EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME);
sd->delay_change_timer = efl_future_then(obj, f,
.success = _delay_change_timer_cb,
.free = _delay_change_timer_cleanup,
.data = sd);
return EINA_TRUE;
}

View File

@ -5,7 +5,7 @@ typedef struct _Efl_Ui_Spin_Button_Data Efl_Ui_Spin_Button_Data;
struct _Efl_Ui_Spin_Button_Data
{
Evas_Object *ent, *inc_button, *dec_button, *text_button;
Ecore_Timer *delay_change_timer; /**< a timer for a delay,changed smart callback */
Eina_Future *delay_change_timer; /**< a timer for a delay,changed smart callback */
Efl_Ui_Layout_Orientation dir;