ecore: allow efl_future_cancel on a promise currently being resolved.
authorCedric BAIL <cedric@osg.samsung.com>
Wed, 19 Oct 2016 20:39:10 +0000 (13:39 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Wed, 19 Oct 2016 20:39:10 +0000 (13:39 -0700)
This is necessary for allowing proper handling of recursive cancel.

src/lib/ecore/efl_promise.c

index aa59b8b..31517c5 100644 (file)
@@ -33,6 +33,7 @@ struct _Efl_Promise_Data
    } set;
 
    Eina_Bool optional : 1;
+   Eina_Bool propagating : 1;
 };
 
 static void
@@ -295,6 +296,11 @@ _efl_loop_future_disconnect(Eo *obj, Efl_Loop_Future_Data *pd)
 static void
 _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;
+
    // Check state
    if (pd->fulfilled)
      {
@@ -526,6 +532,7 @@ _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free
    pd->message = message;
 
    // Send it to all futures
+   pd->propagating = EINA_TRUE;
    EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
      {
         EINA_REFCOUNT_REF(message);
@@ -534,6 +541,7 @@ _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free
         // Trigger the callback
         _efl_loop_future_propagate(f->self, f);
      }
+   pd->propagating = EINA_FALSE;
 
    // Now, we may die.
    efl_unref(obj);
@@ -567,6 +575,7 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
    pd->message = message;
 
    // Send it to each future
+   pd->propagating = EINA_TRUE;
    EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
      {
         EINA_REFCOUNT_REF(message);
@@ -575,6 +584,7 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
         // Trigger the callback
         _efl_loop_future_propagate(f->self, f);
      }
+   pd->propagating = EINA_FALSE;
 
    // Now, we may die.
    efl_unref(obj);