eina: prevent double cancel of ongoing dispatched future.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D8333
This commit is contained in:
Cedric BAIL 2019-03-13 14:49:50 -07:00
parent 6b6faef3a3
commit e859130dd4
1 changed files with 13 additions and 0 deletions

View File

@ -333,6 +333,10 @@ _eina_future_cb_dispatch(Eina_Future *f, const Eina_Value value)
{
Eina_Future_Cb cb = f->cb;
// Cleaning up prev and past to avoid recursion
if (f->next) f->next->prev = NULL;
if (f->prev) f->prev->next = NULL;
f->cb = EINA_FUTURE_DISPATCHED;
if (f->storage) *f->storage = NULL;
@ -364,6 +368,7 @@ _eina_future_dispatch_internal(Eina_Future **f,
_eina_promise_value_dbg("No future to deliver value", NULL, value);
return value;
}
if ((*f)->cb == EINA_FUTURE_DISPATCHED) return value;
next_value = _eina_future_cb_dispatch(*f, value);
*f = _eina_future_free(*f);
return next_value;
@ -396,6 +401,12 @@ _eina_future_dispatch(Eina_Future_Scheduler *scheduler, Eina_Future *f, Eina_Val
return;
}
// Break early if finding a cb that is already dispatching
if (f->cb == EINA_FUTURE_DISPATCHED)
{
eina_value_flush(&next_value);
return;
}
if (next_value.type == &EINA_VALUE_TYPE_PROMISE)
{
if (EINA_UNLIKELY(eina_log_domain_level_check(_promise_log_dom, EINA_LOG_LEVEL_DBG)))
@ -463,6 +474,8 @@ _eina_future_cancel(Eina_Future *f, int err)
while (f)
{
// Stop on partially dispatched future
if (f->cb == EINA_FUTURE_DISPATCHED) break;
if (f->cb)
{
Eina_Value r = _eina_future_cb_dispatch(f, value);