cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=832873259ccc98bf615e4976db92749232f355e8
commit 832873259ccc98bf615e4976db92749232f355e8 Author: Cedric BAIL <ced...@osg.samsung.com> Date: Thu Nov 3 18:02:20 2016 -0700 ecore: fix efl_future_all/race to be setup on already fulfilled future. --- src/lib/ecore/efl_promise.c | 85 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c index fdaf2ea..18f18da 100644 --- a/src/lib/ecore/efl_promise.c +++ b/src/lib/ecore/efl_promise.c @@ -725,10 +725,13 @@ struct _Efl_Promise_Composite Efl_Future *(*future_get)(void *item); + Eina_Error error; + Eina_Bool failed : 1; Eina_Bool progress_triggered : 1; Eina_Bool future_triggered : 1; Eina_Bool done : 1; + Eina_Bool building : 1; }; static Efl_Future * @@ -920,6 +923,26 @@ _efl_accessor_all_free(Efl_Accessor_All *ac) } static void +_real_then_all(Efl_Promise_All *all) +{ + Efl_Accessor_All *ac; + + ac = calloc(1, sizeof (Efl_Accessor_All)); + if (!ac) return ; // We do now the promise and all here + + EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); + + ac->accessor.version = EINA_ACCESSOR_VERSION; + ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(_efl_accessor_all_get_at); + ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_accessor_all_get_container); + ac->accessor.free = FUNC_ACCESSOR_FREE(_efl_accessor_all_free); + ac->all = all; + ac->promise = efl_ref(all->promise); + + efl_promise_value_set(all->promise, &ac->accessor, EINA_FREE_CB(eina_accessor_free)); +} + +static void _then_all(void *data, const Efl_Event *ev) { Efl_Future_Event_Success *success = ev->info; @@ -942,27 +965,22 @@ _then_all(void *data, const Efl_Event *ev) done &= !!fa->d; } + if (all->building) return ; + if (done) { - Efl_Accessor_All *ac; - - ac = calloc(1, sizeof (Efl_Accessor_All)); - if (!ac) return ; // We do now the promise and all here - - EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); - - ac->accessor.version = EINA_ACCESSOR_VERSION; - ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(_efl_accessor_all_get_at); - ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(_efl_accessor_all_get_container); - ac->accessor.free = FUNC_ACCESSOR_FREE(_efl_accessor_all_free); - ac->all = all; - ac->promise = efl_ref(all->promise); - - efl_promise_value_set(all->promise, &ac->accessor, EINA_FREE_CB(eina_accessor_free)); + _real_then_all(all); } } static void +_real_fail_all(Efl_Promise_All *all, Eina_Error error) +{ + efl_promise_failed_set(all->promise, error); + _efl_promise_all_free(all); +} + +static void _fail_all(void *data, const Efl_Event *ev) { Efl_Future_Event_Failure *fail = ev->info; @@ -974,6 +992,12 @@ _fail_all(void *data, const Efl_Event *ev) if (all->failed) return ; all->failed = EINA_TRUE; + if (all->building) + { + all->error = fail->error; + return ; + } + efl_ref(all->promise); // In case of one fail, the entire promise will fail and @@ -992,8 +1016,7 @@ _fail_all(void *data, const Efl_Event *ev) } } - efl_promise_failed_set(all->promise, fail->error); - _efl_promise_all_free(all); + _real_fail_all(all, fail->error); efl_unref(all->promise); } @@ -1044,6 +1067,8 @@ _efl_future_all_new(Eo *provider) all->promise = efl_add(EFL_PROMISE_CLASS, loop); if (!all->promise) goto on_error; + all->building = EINA_TRUE; + return all; on_error: @@ -1054,6 +1079,7 @@ _efl_future_all_new(Eo *provider) static inline Efl_Future * _efl_future_all_done(Efl_Promise_All *all) { + Efl_Future *r; Efl_Future_All *fa; Eina_Array_Iterator iterator; unsigned int i; @@ -1063,7 +1089,25 @@ _efl_future_all_done(Efl_Promise_All *all) efl_event_callback_array_add(all->promise, efl_all_callbacks(), all); - return efl_promise_future_get(all->promise); + r = efl_promise_future_get(all->promise); + + all->building = EINA_FALSE; + + if (all->failed) + { + _real_fail_all(all, all->error); + } + else + { + Eina_Bool done = EINA_TRUE; + + EINA_ARRAY_ITER_NEXT(&all->members, i, fa, iterator) + done &= !!fa->d; + + if (done) _real_then_all(all); + } + + return r; } static Eina_Bool @@ -1242,16 +1286,19 @@ _efl_future_race_new(Eo *provider) static inline Efl_Future * _efl_future_race_done(Efl_Promise_Race *race) { + Efl_Future *r; Efl_Future *fn; Eina_Array_Iterator iterator; unsigned int i; + r = efl_promise_future_get(race->promise); + EINA_ARRAY_ITER_NEXT(&race->members, i, fn, iterator) _efl_loop_future_internal_then(fn, _then_race, _fail_race, _progress, race); efl_event_callback_array_add(race->promise, efl_race_callbacks(), race); - return efl_promise_future_get(race->promise); + return r; } EAPI Efl_Future * --