diff options
author | Cedric BAIL <cedric.bail@free.fr> | 2020-01-22 10:22:06 -0800 |
---|---|---|
committer | Cedric BAIL <cedric.bail@free.fr> | 2020-01-31 10:11:31 -0800 |
commit | 373f2ad7974a064daabcc7ba74db8b553ecfc1e0 (patch) | |
tree | 8cedcd707952ec93132583f3938b69dccafe522d | |
parent | c245b576aad09ac5faeb800de7f7c4fef87c6363 (diff) | |
download | efl-373f2ad7974a064daabcc7ba74db8b553ecfc1e0.tar.gz |
eina: add eina_future_all_iterator and eina_promise_all_iterator.
Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D11180
-rw-r--r-- | src/lib/eina/eina_promise.c | 69 | ||||
-rw-r--r-- | src/lib/eina/eina_promise.h | 32 |
2 files changed, 99 insertions, 2 deletions
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c index f32d835fe4..ece5ad0c96 100644 --- a/src/lib/eina/eina_promise.c +++ b/src/lib/eina/eina_promise.c @@ -8,6 +8,7 @@ #include "eina_mempool.h" #include "eina_promise_private.h" #include "eina_internal.h" +#include "eina_iterator.h" #include <errno.h> #include <stdarg.h> @@ -1223,7 +1224,7 @@ _race_then_cb(void *data, const Eina_Value v, //This is not allowed! assert(v.type != &EINA_VALUE_TYPE_PROMISE); found = _future_unset(&ctx->base, &i, dead_ptr); - assert(found); + assert(found); (void) found; if (ctx->dispatching) return EINA_VALUE_EMPTY; ctx->dispatching = EINA_TRUE; @@ -1262,7 +1263,7 @@ _all_then_cb(void *data, const Eina_Value v, assert(v.type != &EINA_VALUE_TYPE_PROMISE); found = _future_unset(&ctx->base, &i, dead_ptr); - assert(found); + assert(found); (void) found; ctx->processed++; eina_value_array_set(&ctx->values, i, v); @@ -1326,6 +1327,70 @@ promise_proxy_of_future_array_create(Eina_Future *array[], } EAPI Eina_Promise * +eina_promise_all_iterator(Eina_Iterator *it) +{ + All_Promise_Ctx *ctx; + Eina_Future *f; + unsigned int i = 1; + Eina_Bool r; + + EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); + ctx = calloc(1, sizeof(All_Promise_Ctx)); + EINA_SAFETY_ON_NULL_GOTO(ctx, err_ctx); + r = eina_value_array_setup(&ctx->values, EINA_VALUE_TYPE_VALUE, 0); + EINA_SAFETY_ON_FALSE_GOTO(r, err_array); + r = eina_iterator_next(it, (void**) &f); + EINA_SAFETY_ON_FALSE_GOTO(r, err_array); + + ctx->base.promise = eina_promise_new(_scheduler_get(f), _all_promise_cancel, ctx); + EINA_SAFETY_ON_NULL_GOTO(ctx->base.promise, err_array); + + ctx->base.futures_len = 1; + ctx->base.futures = calloc(1, sizeof (Eina_Future *)); + EINA_SAFETY_ON_NULL_GOTO(ctx->base.futures, err_futures); + + ctx->base.futures[0] = eina_future_then(f, _all_then_cb, ctx, NULL); + + EINA_ITERATOR_FOREACH(it, f) + { + Eina_Future **tmp; + + ctx->base.futures_len++; + tmp = realloc(ctx->base.futures, ctx->base.futures_len * sizeof (Eina_Future *)); + + EINA_SAFETY_ON_NULL_GOTO(tmp, err_futures); + ctx->base.futures = tmp; + ctx->base.futures[i] = eina_future_then(f, _all_then_cb, ctx, NULL); + EINA_SAFETY_ON_NULL_GOTO(ctx->base.futures[i++], err_futures); + } + + for (i = 0; i < ctx->base.futures_len; i++) + { + Eina_Value v = { 0 }; + //Stub values... + r = eina_value_setup(&v, EINA_VALUE_TYPE_INT); + EINA_SAFETY_ON_FALSE_GOTO(r, err_futures); + r = eina_value_array_append(&ctx->values, v); + eina_value_flush(&v); + EINA_SAFETY_ON_FALSE_GOTO(r, err_futures); + } + return ctx->base.promise; + + err_futures: + while (i >= 1) _eina_future_free(ctx->base.futures[--i]); + free(ctx->base.futures); + ctx->base.futures = NULL; + + eina_mempool_free(_promise_mp, ctx->base.promise); + eina_value_flush(&ctx->values); + err_array: + free(ctx); + err_ctx: + eina_iterator_free(it); + return NULL; +} + +EAPI Eina_Promise * eina_promise_all_array(Eina_Future *array[]) { All_Promise_Ctx *ctx; diff --git a/src/lib/eina/eina_promise.h b/src/lib/eina/eina_promise.h index 9de125463e..548d162aa0 100644 --- a/src/lib/eina/eina_promise.h +++ b/src/lib/eina/eina_promise.h @@ -1372,6 +1372,22 @@ EAPI Eina_Future_Desc eina_future_cb_easy_from_desc(const Eina_Future_Cb_Easy_De EAPI Eina_Promise *eina_promise_all_array(Eina_Future *array[]) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; /** + * Creates an all promise from an iterator. + * + * Creates a promise that is resolved once all the futures + * from the @p iterator are resolved. + * The promise is resolved with an Eina_Value type array which + * contains EINA_VALUE_TYPE_VALUE elements. The result array is + * ordered according to the @p iterator order. + * + * @param[in] iterator An iterator of futures. Will be destroyed after the call. + * @return A promise or @c NULL on error. + * @note On error all the futures will be CANCELED. + * @see eina_future_all_iterator() + */ +EAPI Eina_Promise *eina_promise_all_iterator(Eina_Iterator *iterator) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** * Creates a race promise. * * Creates a promise that resolves when a future from the @p array @@ -1558,6 +1574,22 @@ eina_future_all_array(Eina_Future *array[]) } /** + * Creates a future that will be resolved once all futures from @p iterator are resolved. + * This is a helper over eina_promise_all_iterator() + * + * @param[in] iterator An iterator containing futures. Will be destroyed on exit of the function. + * @return A future. + * @see eina_promise_all_iterator() + */ +static inline Eina_Future * +eina_future_all_iterator(Eina_Iterator *iterator) +{ + Eina_Promise *p = eina_promise_all_iterator(iterator); + if (!p) return NULL; + return eina_future_new(p); +} + +/** * Creates a future that will be resolved once a future @p array is resolved. * This is a helper over eina_promise_race_array() * |