diff options
author | Cedric BAIL <cedric@osg.samsung.com> | 2017-02-07 10:54:12 -0800 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2017-02-27 15:29:12 -0800 |
commit | 9ea4a03f342989a5000a3e41405f33b6667579ab (patch) | |
tree | 00a7d42d08400faa224916e7d979cf117c0a0974 | |
parent | 67e350361fb3d3b4ab98b7559a51d3ce52b059e7 (diff) | |
download | efl-devs/cedric/wref.tar.gz |
ecore: try to clean up weak ref ahead of the future death.devs/cedric/wref
-rw-r--r-- | src/lib/ecore/efl_promise.c | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c index a9e5177bc9..02e0e3cad1 100644 --- a/src/lib/ecore/efl_promise.c +++ b/src/lib/ecore/efl_promise.c @@ -76,9 +76,8 @@ struct _Efl_Loop_Future_Data Efl_Promise_Msg *message; Efl_Promise_Data *promise; -#ifndef NDEBUG - int wref; -#endif + Eina_Inarray *wref; + unsigned char propagating; Eina_Bool fulfilled : 1; @@ -130,6 +129,19 @@ _efl_loop_future_failure(Efl_Event *ev, Efl_Loop_Future_Data *pd, Eina_Error err Efl_Loop_Future_Callback *cb; Efl_Future_Event_Failure chain_fail; + // There is no way around, we need to cleanup wref before doing anything. + // This means we can't rely on Eo wref for Efl_Future at all. + if (pd->wref) + { + Eo **wref; + + EINA_INARRAY_FOREACH(pd->wref, wref) + *wref = NULL; + + eina_inarray_free(pd->wref); + pd->wref = NULL; + } + ev->info = &chain_fail; ev->desc = EFL_FUTURE_EVENT_FAILURE; @@ -348,12 +360,10 @@ _efl_loop_future_cancel(Eo *obj, Efl_Loop_Future_Data *pd) return; } -#ifndef NDEBUG if (!pd->wref) { WRN("Calling cancel should be only done on a weak reference. Look at efl_future_use."); } -#endif pd->fulfilled = EINA_TRUE; @@ -414,6 +424,17 @@ _efl_loop_future_efl_object_destructor(Eo *obj, Efl_Loop_Future_Data *pd) { Eo *promise = NULL; + if (pd->wref) + { + Eo **wref; + + EINA_INARRAY_FOREACH(pd->wref, wref) + *wref = NULL; + + eina_inarray_free(pd->wref); + pd->wref = NULL; + } + if (!pd->fulfilled) { ERR("Lost reference to a future without fulfilling it. Forcefully cancelling it."); @@ -454,23 +475,26 @@ _efl_loop_future_efl_object_destructor(Eo *obj, Efl_Loop_Future_Data *pd) efl_unref(pd->loop); } -#ifndef NDEBUG static void -_efl_future_wref_add(Eo *obj, Efl_Loop_Future_Data *pd, Eo **wref) +_efl_future_wref_add(Eo *obj EINA_UNUSED, Efl_Loop_Future_Data *pd, Eo **wref) { - efl_wref_add(efl_super(obj, EFL_LOOP_FUTURE_CLASS), wref); + if (!pd->wref) pd->wref = eina_inarray_new(sizeof (Eo *), 2); - pd->wref++; + eina_inarray_push(pd->wref, wref); } static void -_efl_future_wref_del(Eo *obj, Efl_Loop_Future_Data *pd, Eo **wref) +_efl_future_wref_del(Eo *obj EINA_UNUSED, Efl_Loop_Future_Data *pd, Eo **wref) { - efl_wref_del(efl_super(obj, EFL_LOOP_FUTURE_CLASS), wref); + if (!pd->wref) return ; + eina_inarray_remove(pd->wref, wref); - pd->wref--; + if (eina_inarray_count(pd->wref) == 0) + { + eina_inarray_free(pd->wref); + pd->wref = NULL; + } } -#endif static Efl_Object * _efl_loop_future_efl_object_provider_find(Eo *obj EINA_UNUSED, Efl_Loop_Future_Data *pd, const Efl_Object *klass) @@ -487,10 +511,8 @@ static Eina_Bool _efl_loop_future_class_initializer(Efl_Class *klass) { EFL_OPS_DEFINE(ops, -#ifndef NDEBUG EFL_OBJECT_OP_FUNC(efl_wref_add, _efl_future_wref_add), EFL_OBJECT_OP_FUNC(efl_wref_del, _efl_future_wref_del), -#endif EFL_OBJECT_OP_FUNC(efl_provider_find, _efl_loop_future_efl_object_provider_find), EFL_OBJECT_OP_FUNC(efl_future_then, _efl_loop_future_then), EFL_OBJECT_OP_FUNC(efl_future_cancel, _efl_loop_future_cancel), |