cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6321630d32994bf4c575879e54762aba153f0b63

commit 6321630d32994bf4c575879e54762aba153f0b63
Author: Cedric Bail <[email protected]>
Date:   Fri Oct 21 12:44:15 2016 -0700

    ecore: force fully resolve a future on cancel during recursive call.
---
 src/lib/ecore/efl_promise.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c
index 31517c5..8cbde0e 100644
--- a/src/lib/ecore/efl_promise.c
+++ b/src/lib/ecore/efl_promise.c
@@ -95,6 +95,10 @@ _efl_loop_future_success(Efl_Event *ev, Efl_Loop_Future_Data 
*pd, void *value)
 
    EINA_INLIST_FREE(pd->callbacks, cb)
      {
+        // Remove callback early to avoid double execution while
+        // doing recursive call
+        pd->callbacks = eina_inlist_remove(pd->callbacks, pd->callbacks);
+
         if (cb->next)
           {
              chain_success.next = cb->next;
@@ -109,7 +113,6 @@ _efl_loop_future_success(Efl_Event *ev, 
Efl_Loop_Future_Data *pd, void *value)
              chain_success.value = value;
           }
 
-        pd->callbacks = eina_inlist_remove(pd->callbacks, pd->callbacks);
         free(cb);
      }
 }
@@ -127,16 +130,36 @@ _efl_loop_future_failure(Efl_Event *ev, 
Efl_Loop_Future_Data *pd, Eina_Error err
 
    EINA_INLIST_FREE(pd->callbacks, cb)
      {
+        // Remove callback early to avoid double execution while
+        // doing recursive call
+        pd->callbacks = eina_inlist_remove(pd->callbacks, pd->callbacks);
+
         chain_fail.next = cb->next;
 
         if (cb->failure) cb->failure((void*) cb->data, ev);
 
-        pd->callbacks = eina_inlist_remove(pd->callbacks, pd->callbacks);
         free(cb);
      }
 }
 
 static void
+_efl_loop_future_propagate_force(Eo *obj, Efl_Loop_Future_Data *pd)
+{
+   Efl_Event ev;
+
+   ev.object = obj;
+
+   if (pd->promise->message->error == 0)
+     {
+        _efl_loop_future_success(&ev, pd, pd->message->value);
+     }
+   else
+     {
+        _efl_loop_future_failure(&ev, pd, pd->message->error);
+     }
+}
+
+static void
 _efl_loop_future_propagate(Eo *obj, Efl_Loop_Future_Data *pd)
 {
    Efl_Event ev;
@@ -299,7 +322,14 @@ _efl_loop_future_cancel(Eo *obj, Efl_Loop_Future_Data *pd)
    // We do allow for calling cancel during the propagation phase
    // as the other proper fix is to wype out all future reference before
    // starting propagating things.
-   if (pd->promise && pd->promise->propagating) return;
+   if (pd->promise && pd->promise->propagating)
+     {
+        efl_ref(obj);
+
+        _efl_loop_future_propagate_force(obj, pd);
+
+        goto disconnect;
+     }
 
    // Check state
    if (pd->fulfilled)
@@ -322,6 +352,7 @@ _efl_loop_future_cancel(Eo *obj, Efl_Loop_Future_Data *pd)
 
    _efl_loop_future_propagate(obj, pd);
 
+ disconnect:
    _efl_loop_future_disconnect(obj, pd);
 
    efl_unref(obj);

-- 


Reply via email to