bu5hm4n pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=477611f01460f4b9881f2b5dd4b88f463d8f81b0

commit 477611f01460f4b9881f2b5dd4b88f463d8f81b0
Author: Cedric BAIL <cedric.b...@free.fr>
Date:   Thu Jul 11 15:53:54 2019 -0700

    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 <m...@marcel-hollerbach.de>
    Differential Revision: https://phab.enlightenment.org/D9298
---
 src/lib/elementary/efl_ui_spin_button.c         | 27 ++++++++++++++++---------
 src/lib/elementary/efl_ui_spin_button_private.h |  2 +-
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/lib/elementary/efl_ui_spin_button.c 
b/src/lib/elementary/efl_ui_spin_button.c
index f14c365ba8..6974428dc4 100644
--- a/src/lib/elementary/efl_ui_spin_button.c
+++ b/src/lib/elementary/efl_ui_spin_button.c
@@ -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);
 
-   sd->delay_change_timer = NULL;
-   efl_event_callback_call(data, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
+   return v;
+}
 
-   return ECORE_CALLBACK_CANCEL;
+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;
 }
 
 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;
 }
diff --git a/src/lib/elementary/efl_ui_spin_button_private.h 
b/src/lib/elementary/efl_ui_spin_button_private.h
index 1c32c75a6d..5c6d0a977b 100644
--- a/src/lib/elementary/efl_ui_spin_button_private.h
+++ b/src/lib/elementary/efl_ui_spin_button_private.h
@@ -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;
 

-- 


Reply via email to