forked from enlightenment/efl
ecore: allow multiple nested recursion of the same promise/future to happen at the same time.
This commit is contained in:
parent
fb8d139ad0
commit
bfcc66e4eb
|
@ -25,6 +25,8 @@ struct _Efl_Promise_Data
|
||||||
Efl_Promise_Msg *message;
|
Efl_Promise_Msg *message;
|
||||||
Eina_List *futures;
|
Eina_List *futures;
|
||||||
|
|
||||||
|
unsigned char propagating;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Eina_Bool future : 1;
|
Eina_Bool future : 1;
|
||||||
Eina_Bool future_triggered : 1;
|
Eina_Bool future_triggered : 1;
|
||||||
|
@ -33,7 +35,6 @@ struct _Efl_Promise_Data
|
||||||
} set;
|
} set;
|
||||||
|
|
||||||
Eina_Bool optional : 1;
|
Eina_Bool optional : 1;
|
||||||
Eina_Bool propagating : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -76,6 +77,7 @@ struct _Efl_Loop_Future_Data
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
int wref;
|
int wref;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned char propagating;
|
||||||
|
|
||||||
Eina_Bool fulfilled : 1;
|
Eina_Bool fulfilled : 1;
|
||||||
Eina_Bool death : 1;
|
Eina_Bool death : 1;
|
||||||
|
@ -94,6 +96,7 @@ _efl_loop_future_success(Efl_Event *ev, Efl_Loop_Future_Data *pd, void *value)
|
||||||
|
|
||||||
chain_success.value = value;
|
chain_success.value = value;
|
||||||
|
|
||||||
|
pd->propagating++;
|
||||||
EINA_INLIST_FREE(pd->callbacks, cb)
|
EINA_INLIST_FREE(pd->callbacks, cb)
|
||||||
{
|
{
|
||||||
// Remove callback early to avoid double execution while
|
// Remove callback early to avoid double execution while
|
||||||
|
@ -116,6 +119,7 @@ _efl_loop_future_success(Efl_Event *ev, Efl_Loop_Future_Data *pd, void *value)
|
||||||
|
|
||||||
free(cb);
|
free(cb);
|
||||||
}
|
}
|
||||||
|
pd->propagating--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -129,6 +133,7 @@ _efl_loop_future_failure(Efl_Event *ev, Efl_Loop_Future_Data *pd, Eina_Error err
|
||||||
|
|
||||||
chain_fail.error = error;
|
chain_fail.error = error;
|
||||||
|
|
||||||
|
pd->propagating++;
|
||||||
EINA_INLIST_FREE(pd->callbacks, cb)
|
EINA_INLIST_FREE(pd->callbacks, cb)
|
||||||
{
|
{
|
||||||
// Remove callback early to avoid double execution while
|
// Remove callback early to avoid double execution while
|
||||||
|
@ -141,6 +146,7 @@ _efl_loop_future_failure(Efl_Event *ev, Efl_Loop_Future_Data *pd, Eina_Error err
|
||||||
|
|
||||||
free(cb);
|
free(cb);
|
||||||
}
|
}
|
||||||
|
pd->propagating--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -323,7 +329,8 @@ _efl_loop_future_cancel(Eo *obj, Efl_Loop_Future_Data *pd)
|
||||||
// We do allow for calling cancel during the propagation phase
|
// We do allow for calling cancel during the propagation phase
|
||||||
// as the other proper fix is to wype out all future reference before
|
// as the other proper fix is to wype out all future reference before
|
||||||
// starting propagating things.
|
// starting propagating things.
|
||||||
if (pd->promise && pd->promise->propagating)
|
if (pd->propagating ||
|
||||||
|
(pd->promise && pd->promise->propagating))
|
||||||
{
|
{
|
||||||
efl_ref(obj);
|
efl_ref(obj);
|
||||||
|
|
||||||
|
@ -353,9 +360,9 @@ _efl_loop_future_cancel(Eo *obj, Efl_Loop_Future_Data *pd)
|
||||||
|
|
||||||
_efl_loop_future_propagate(obj, pd);
|
_efl_loop_future_propagate(obj, pd);
|
||||||
|
|
||||||
disconnect:
|
|
||||||
_efl_loop_future_disconnect(obj, pd);
|
_efl_loop_future_disconnect(obj, pd);
|
||||||
|
|
||||||
|
disconnect:
|
||||||
efl_unref(obj);
|
efl_unref(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +571,7 @@ _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free
|
||||||
pd->message = message;
|
pd->message = message;
|
||||||
|
|
||||||
// Send it to all futures
|
// Send it to all futures
|
||||||
pd->propagating = EINA_TRUE;
|
pd->propagating++;
|
||||||
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
|
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
|
||||||
{
|
{
|
||||||
EINA_REFCOUNT_REF(message);
|
EINA_REFCOUNT_REF(message);
|
||||||
|
@ -573,7 +580,7 @@ _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free
|
||||||
// Trigger the callback
|
// Trigger the callback
|
||||||
_efl_loop_future_propagate(f->self, f);
|
_efl_loop_future_propagate(f->self, f);
|
||||||
}
|
}
|
||||||
pd->propagating = EINA_FALSE;
|
pd->propagating--;
|
||||||
|
|
||||||
// Now, we may die.
|
// Now, we may die.
|
||||||
efl_unref(obj);
|
efl_unref(obj);
|
||||||
|
@ -607,7 +614,7 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
|
||||||
pd->message = message;
|
pd->message = message;
|
||||||
|
|
||||||
// Send it to each future
|
// Send it to each future
|
||||||
pd->propagating = EINA_TRUE;
|
pd->propagating++;
|
||||||
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
|
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
|
||||||
{
|
{
|
||||||
EINA_REFCOUNT_REF(message);
|
EINA_REFCOUNT_REF(message);
|
||||||
|
@ -616,7 +623,7 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
|
||||||
// Trigger the callback
|
// Trigger the callback
|
||||||
_efl_loop_future_propagate(f->self, f);
|
_efl_loop_future_propagate(f->self, f);
|
||||||
}
|
}
|
||||||
pd->propagating = EINA_FALSE;
|
pd->propagating--;
|
||||||
|
|
||||||
// Now, we may die.
|
// Now, we may die.
|
||||||
efl_unref(obj);
|
efl_unref(obj);
|
||||||
|
|
Loading…
Reference in New Issue