diff options
author | Marcel Hollerbach <mail@marcel-hollerbach.de> | 2021-04-10 12:15:47 +0200 |
---|---|---|
committer | Marcel Hollerbach <mail@marcel-hollerbach.de> | 2021-04-10 12:15:47 +0200 |
commit | 4617ba2e9350d92c15e7fe2e1e0c03a43fb3d93e (patch) | |
tree | c82ba041750240914ac58c2a1efec34d386d4436 | |
parent | c88f9abb40044bd4dae6cddbbab7bbfcf346db7a (diff) | |
download | efl-devs/bu5hm4n/tmp.tar.gz |
eina_promise: do not self feedback when cancelingdevs/bu5hm4n/tmp
when canceling a all_promise it will cancel all futures. When that
happens, and one future is containing a promise, the value is unrolled,
and delivered as "Operation canceled" if this is happening to the last
future in all or any in race, the promise will then free its base ctx
which is already happening due to canceling.
With this this is not happening anymore.
-rw-r--r-- | src/lib/eina/eina_promise.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c index 4fe51206e4..873d3cb13d 100644 --- a/src/lib/eina/eina_promise.c +++ b/src/lib/eina/eina_promise.c @@ -1148,6 +1148,7 @@ typedef struct _Base_Ctx { Eina_Promise *promise; Eina_Future **futures; unsigned int futures_len; + Eina_Bool cancelled : 1; } Base_Ctx; typedef struct _All_Promise_Ctx { @@ -1173,6 +1174,7 @@ _base_ctx_clean(Base_Ctx *ctx) static void _all_promise_ctx_free(All_Promise_Ctx *ctx) { + DBG("Cleaning base_ctx for %p", ctx); _base_ctx_clean(&ctx->base); eina_value_flush(&ctx->values); free(ctx); @@ -1181,12 +1183,16 @@ _all_promise_ctx_free(All_Promise_Ctx *ctx) static void _all_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED) { - _all_promise_ctx_free(data); + All_Promise_Ctx *ctx = data; + + ctx->base.cancelled = 1; + _all_promise_ctx_free(ctx); } static void _race_promise_ctx_free(Race_Promise_Ctx *ctx) { + DBG("Cleaning base_ctx for %p", ctx); _base_ctx_clean(&ctx->base); free(ctx); } @@ -1194,6 +1200,9 @@ _race_promise_ctx_free(Race_Promise_Ctx *ctx) static void _race_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED) { + Race_Promise_Ctx *ctx = data; + + ctx->base.cancelled = 1; _race_promise_ctx_free(data); } @@ -1233,7 +1242,8 @@ _race_then_cb(void *data, const Eina_Value v, ctx->dispatching = EINA_TRUE; //By freeing the race_ctx all the other futures will be cancelled. - _race_promise_ctx_free(ctx); + if (!ctx->base.cancelled) + _race_promise_ctx_free(ctx); r = eina_value_struct_setup(&result, &RACE_STRUCT_DESC); EINA_SAFETY_ON_FALSE_GOTO(r, err_setup); @@ -1275,7 +1285,8 @@ _all_then_cb(void *data, const Eina_Value v, //We're in a safe context (from mainloop), so we can avoid scheduling a new dispatch _eina_promise_clean_dispatch(ctx->base.promise, ctx->values); ctx->values = EINA_VALUE_EMPTY; /* flushed in _eina_promise_clean_dispatch() */ - _all_promise_ctx_free(ctx); + if (!ctx->base.cancelled) + _all_promise_ctx_free(ctx); } return v; } |