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) |
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 @@ | |||
8 | #include "eina_mempool.h" | 8 | #include "eina_mempool.h" |
9 | #include "eina_promise_private.h" | 9 | #include "eina_promise_private.h" |
10 | #include "eina_internal.h" | 10 | #include "eina_internal.h" |
11 | #include "eina_iterator.h" | ||
11 | 12 | ||
12 | #include <errno.h> | 13 | #include <errno.h> |
13 | #include <stdarg.h> | 14 | #include <stdarg.h> |
@@ -1223,7 +1224,7 @@ _race_then_cb(void *data, const Eina_Value v, | |||
1223 | //This is not allowed! | 1224 | //This is not allowed! |
1224 | assert(v.type != &EINA_VALUE_TYPE_PROMISE); | 1225 | assert(v.type != &EINA_VALUE_TYPE_PROMISE); |
1225 | found = _future_unset(&ctx->base, &i, dead_ptr); | 1226 | found = _future_unset(&ctx->base, &i, dead_ptr); |
1226 | assert(found); | 1227 | assert(found); (void) found; |
1227 | 1228 | ||
1228 | if (ctx->dispatching) return EINA_VALUE_EMPTY; | 1229 | if (ctx->dispatching) return EINA_VALUE_EMPTY; |
1229 | ctx->dispatching = EINA_TRUE; | 1230 | ctx->dispatching = EINA_TRUE; |
@@ -1262,7 +1263,7 @@ _all_then_cb(void *data, const Eina_Value v, | |||
1262 | assert(v.type != &EINA_VALUE_TYPE_PROMISE); | 1263 | assert(v.type != &EINA_VALUE_TYPE_PROMISE); |
1263 | 1264 | ||
1264 | found = _future_unset(&ctx->base, &i, dead_ptr); | 1265 | found = _future_unset(&ctx->base, &i, dead_ptr); |
1265 | assert(found); | 1266 | assert(found); (void) found; |
1266 | 1267 | ||
1267 | ctx->processed++; | 1268 | ctx->processed++; |
1268 | eina_value_array_set(&ctx->values, i, v); | 1269 | eina_value_array_set(&ctx->values, i, v); |
@@ -1326,6 +1327,70 @@ promise_proxy_of_future_array_create(Eina_Future *array[], | |||
1326 | } | 1327 | } |
1327 | 1328 | ||
1328 | EAPI Eina_Promise * | 1329 | EAPI Eina_Promise * |
1330 | eina_promise_all_iterator(Eina_Iterator *it) | ||
1331 | { | ||
1332 | All_Promise_Ctx *ctx; | ||
1333 | Eina_Future *f; | ||
1334 | unsigned int i = 1; | ||
1335 | Eina_Bool r; | ||
1336 | |||
1337 | EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); | ||
1338 | ctx = calloc(1, sizeof(All_Promise_Ctx)); | ||
1339 | EINA_SAFETY_ON_NULL_GOTO(ctx, err_ctx); | ||
1340 | r = eina_value_array_setup(&ctx->values, EINA_VALUE_TYPE_VALUE, 0); | ||
1341 | EINA_SAFETY_ON_FALSE_GOTO(r, err_array); | ||
1342 | r = eina_iterator_next(it, (void**) &f); | ||
1343 | EINA_SAFETY_ON_FALSE_GOTO(r, err_array); | ||
1344 | |||
1345 | ctx->base.promise = eina_promise_new(_scheduler_get(f), _all_promise_cancel, ctx); | ||
1346 | EINA_SAFETY_ON_NULL_GOTO(ctx->base.promise, err_array); | ||
1347 | |||
1348 | ctx->base.futures_len = 1; | ||
1349 | ctx->base.futures = calloc(1, sizeof (Eina_Future *)); | ||
1350 | EINA_SAFETY_ON_NULL_GOTO(ctx->base.futures, err_futures); | ||
1351 | |||
1352 | ctx->base.futures[0] = eina_future_then(f, _all_then_cb, ctx, NULL); | ||
1353 | |||
1354 | EINA_ITERATOR_FOREACH(it, f) | ||
1355 | { | ||
1356 | Eina_Future **tmp; | ||
1357 | |||
1358 | ctx->base.futures_len++; | ||
1359 | tmp = realloc(ctx->base.futures, ctx->base.futures_len * sizeof (Eina_Future *)); | ||
1360 | |||
1361 | EINA_SAFETY_ON_NULL_GOTO(tmp, err_futures); | ||
1362 | ctx->base.futures = tmp; | ||
1363 | ctx->base.futures[i] = eina_future_then(f, _all_then_cb, ctx, NULL); | ||
1364 | EINA_SAFETY_ON_NULL_GOTO(ctx->base.futures[i++], err_futures); | ||
1365 | } | ||
1366 | |||
1367 | for (i = 0; i < ctx->base.futures_len; i++) | ||
1368 | { | ||
1369 | Eina_Value v = { 0 }; | ||
1370 | //Stub values... | ||
1371 | r = eina_value_setup(&v, EINA_VALUE_TYPE_INT); | ||
1372 | EINA_SAFETY_ON_FALSE_GOTO(r, err_futures); | ||
1373 | r = eina_value_array_append(&ctx->values, v); | ||
1374 | eina_value_flush(&v); | ||
1375 | EINA_SAFETY_ON_FALSE_GOTO(r, err_futures); | ||
1376 | } | ||
1377 | return ctx->base.promise; | ||
1378 | |||
1379 | err_futures: | ||
1380 | while (i >= 1) _eina_future_free(ctx->base.futures[--i]); | ||
1381 | free(ctx->base.futures); | ||
1382 | ctx->base.futures = NULL; | ||
1383 | |||
1384 | eina_mempool_free(_promise_mp, ctx->base.promise); | ||
1385 | eina_value_flush(&ctx->values); | ||
1386 | err_array: | ||
1387 | free(ctx); | ||
1388 | err_ctx: | ||
1389 | eina_iterator_free(it); | ||
1390 | return NULL; | ||
1391 | } | ||
1392 | |||
1393 | EAPI Eina_Promise * | ||
1329 | eina_promise_all_array(Eina_Future *array[]) | 1394 | eina_promise_all_array(Eina_Future *array[]) |
1330 | { | 1395 | { |
1331 | All_Promise_Ctx *ctx; | 1396 | 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 | |||
1372 | EAPI Eina_Promise *eina_promise_all_array(Eina_Future *array[]) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; | 1372 | EAPI Eina_Promise *eina_promise_all_array(Eina_Future *array[]) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; |
1373 | 1373 | ||
1374 | /** | 1374 | /** |
1375 | * Creates an all promise from an iterator. | ||
1376 | * | ||
1377 | * Creates a promise that is resolved once all the futures | ||
1378 | * from the @p iterator are resolved. | ||
1379 | * The promise is resolved with an Eina_Value type array which | ||
1380 | * contains EINA_VALUE_TYPE_VALUE elements. The result array is | ||
1381 | * ordered according to the @p iterator order. | ||
1382 | * | ||
1383 | * @param[in] iterator An iterator of futures. Will be destroyed after the call. | ||
1384 | * @return A promise or @c NULL on error. | ||
1385 | * @note On error all the futures will be CANCELED. | ||
1386 | * @see eina_future_all_iterator() | ||
1387 | */ | ||
1388 | EAPI Eina_Promise *eina_promise_all_iterator(Eina_Iterator *iterator) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; | ||
1389 | |||
1390 | /** | ||
1375 | * Creates a race promise. | 1391 | * Creates a race promise. |
1376 | * | 1392 | * |
1377 | * Creates a promise that resolves when a future from the @p array | 1393 | * Creates a promise that resolves when a future from the @p array |
@@ -1558,6 +1574,22 @@ eina_future_all_array(Eina_Future *array[]) | |||
1558 | } | 1574 | } |
1559 | 1575 | ||
1560 | /** | 1576 | /** |
1577 | * Creates a future that will be resolved once all futures from @p iterator are resolved. | ||
1578 | * This is a helper over eina_promise_all_iterator() | ||
1579 | * | ||
1580 | * @param[in] iterator An iterator containing futures. Will be destroyed on exit of the function. | ||
1581 | * @return A future. | ||
1582 | * @see eina_promise_all_iterator() | ||
1583 | */ | ||
1584 | static inline Eina_Future * | ||
1585 | eina_future_all_iterator(Eina_Iterator *iterator) | ||
1586 | { | ||
1587 | Eina_Promise *p = eina_promise_all_iterator(iterator); | ||
1588 | if (!p) return NULL; | ||
1589 | return eina_future_new(p); | ||
1590 | } | ||
1591 | |||
1592 | /** | ||
1561 | * Creates a future that will be resolved once a future @p array is resolved. | 1593 | * Creates a future that will be resolved once a future @p array is resolved. |
1562 | * This is a helper over eina_promise_race_array() | 1594 | * This is a helper over eina_promise_race_array() |
1563 | * | 1595 | * |