summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2021-04-10 12:15:47 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2021-04-10 12:15:47 +0200
commit4617ba2e9350d92c15e7fe2e1e0c03a43fb3d93e (patch)
treec82ba041750240914ac58c2a1efec34d386d4436
parentc88f9abb40044bd4dae6cddbbab7bbfcf346db7a (diff)
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.c17
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 {
1148 Eina_Promise *promise; 1148 Eina_Promise *promise;
1149 Eina_Future **futures; 1149 Eina_Future **futures;
1150 unsigned int futures_len; 1150 unsigned int futures_len;
1151 Eina_Bool cancelled : 1;
1151} Base_Ctx; 1152} Base_Ctx;
1152 1153
1153typedef struct _All_Promise_Ctx { 1154typedef struct _All_Promise_Ctx {
@@ -1173,6 +1174,7 @@ _base_ctx_clean(Base_Ctx *ctx)
1173static void 1174static void
1174_all_promise_ctx_free(All_Promise_Ctx *ctx) 1175_all_promise_ctx_free(All_Promise_Ctx *ctx)
1175{ 1176{
1177 DBG("Cleaning base_ctx for %p", ctx);
1176 _base_ctx_clean(&ctx->base); 1178 _base_ctx_clean(&ctx->base);
1177 eina_value_flush(&ctx->values); 1179 eina_value_flush(&ctx->values);
1178 free(ctx); 1180 free(ctx);
@@ -1181,12 +1183,16 @@ _all_promise_ctx_free(All_Promise_Ctx *ctx)
1181static void 1183static void
1182_all_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED) 1184_all_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED)
1183{ 1185{
1184 _all_promise_ctx_free(data); 1186 All_Promise_Ctx *ctx = data;
1187
1188 ctx->base.cancelled = 1;
1189 _all_promise_ctx_free(ctx);
1185} 1190}
1186 1191
1187static void 1192static void
1188_race_promise_ctx_free(Race_Promise_Ctx *ctx) 1193_race_promise_ctx_free(Race_Promise_Ctx *ctx)
1189{ 1194{
1195 DBG("Cleaning base_ctx for %p", ctx);
1190 _base_ctx_clean(&ctx->base); 1196 _base_ctx_clean(&ctx->base);
1191 free(ctx); 1197 free(ctx);
1192} 1198}
@@ -1194,6 +1200,9 @@ _race_promise_ctx_free(Race_Promise_Ctx *ctx)
1194static void 1200static void
1195_race_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED) 1201_race_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED)
1196{ 1202{
1203 Race_Promise_Ctx *ctx = data;
1204
1205 ctx->base.cancelled = 1;
1197 _race_promise_ctx_free(data); 1206 _race_promise_ctx_free(data);
1198} 1207}
1199 1208
@@ -1233,7 +1242,8 @@ _race_then_cb(void *data, const Eina_Value v,
1233 ctx->dispatching = EINA_TRUE; 1242 ctx->dispatching = EINA_TRUE;
1234 1243
1235 //By freeing the race_ctx all the other futures will be cancelled. 1244 //By freeing the race_ctx all the other futures will be cancelled.
1236 _race_promise_ctx_free(ctx); 1245 if (!ctx->base.cancelled)
1246 _race_promise_ctx_free(ctx);
1237 1247
1238 r = eina_value_struct_setup(&result, &RACE_STRUCT_DESC); 1248 r = eina_value_struct_setup(&result, &RACE_STRUCT_DESC);
1239 EINA_SAFETY_ON_FALSE_GOTO(r, err_setup); 1249 EINA_SAFETY_ON_FALSE_GOTO(r, err_setup);
@@ -1275,7 +1285,8 @@ _all_then_cb(void *data, const Eina_Value v,
1275 //We're in a safe context (from mainloop), so we can avoid scheduling a new dispatch 1285 //We're in a safe context (from mainloop), so we can avoid scheduling a new dispatch
1276 _eina_promise_clean_dispatch(ctx->base.promise, ctx->values); 1286 _eina_promise_clean_dispatch(ctx->base.promise, ctx->values);
1277 ctx->values = EINA_VALUE_EMPTY; /* flushed in _eina_promise_clean_dispatch() */ 1287 ctx->values = EINA_VALUE_EMPTY; /* flushed in _eina_promise_clean_dispatch() */
1278 _all_promise_ctx_free(ctx); 1288 if (!ctx->base.cancelled)
1289 _all_promise_ctx_free(ctx);
1279 } 1290 }
1280 return v; 1291 return v;
1281} 1292}