summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-07-29 00:00:49 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-07-29 00:02:03 +0900
commit742fbc5717f3b70a4f3c900f648f9cc761985966 (patch)
tree01f5e8578e2329d51aaf6eaaa5c1d185c19ec232
parent63a3da0c0fa2e4a05cd214ccb39c703be137ab5d (diff)
downloadefl-742fbc5717f3b70a4f3c900f648f9cc761985966.tar.gz
evas canvas destruction - detect zombie objs and hack at them with axes
ok. so here's the issue at least now. we have eo objects in the canvas and they have a refcount of 2 user_refcount is 0. the calls stack does NOT show we are calling callbacks at that time on these objects. they are not in the backtrace (the canvas is, the objects themselves are not). SOMETHING is keeping 2 eo "internal" refs on these objects and i have no idea what/how/who. it's a royal pain in the butt to find out as the only way is lots and lots of logging and you get drowned in the logging... so what I have now done is a super ugly workaround that detects these zombie objects that refuse to die and just FORCES them to die when the evas canvas frees and clears out layers. ac10a00acc6bacf01bfd208cc78b4eb2a6a925d8 doesn't really cause the issue, it just brings it out in the open for all to see far more easily. but something is deeply wrong SOMEWHERE with SOME objects and our refcounts. this fixes T4187
-rw-r--r--src/lib/eo/Eo.h6
-rw-r--r--src/lib/eo/eo.c16
-rw-r--r--src/lib/evas/canvas/evas_main.c14
3 files changed, 36 insertions, 0 deletions
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 293234a15c..f72ee699fc 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -1132,6 +1132,12 @@ EAPI const Eo_Event_Description *eo_base_legacy_only_event_description_get(const
/**
* @}
*/
+
+
+ /* Private for EFL internal use only. Do not use these! */
+EAPI int ___eo_ref2_get(const Eo *obj_id);
+EAPI void ___eo_ref2_reset(const Eo *obj_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index a7df2b5a33..0690c446f9 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -1479,6 +1479,22 @@ eo_ref_get(const Eo *obj_id)
return obj->user_refcount;
}
+EAPI int
+___eo_ref2_get(const Eo *obj_id)
+{
+ EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, 0);
+
+ return obj->refcount;
+}
+
+EAPI void
+___eo_ref2_reset(const Eo *obj_id)
+{
+ EO_OBJ_POINTER_RETURN(obj_id, obj);
+ obj->refcount = 0;
+}
+
+
EAPI void
eo_del_intercept_set(Eo *obj_id, Eo_Del_Intercept del_intercept_func)
{
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index 7f7afa2f54..44959b3f9c 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -251,7 +251,9 @@ _evas_canvas_eo_base_destructor(Eo *eo_e, Evas_Public_Data *e)
del = EINA_FALSE;
EINA_INLIST_FOREACH(e->layers, lay)
{
+ Eo *eo_obj;
Evas_Object_Protected_Data *o;
+ Eina_List *unrefs = NULL;
evas_layer_pre_free(lay);
@@ -264,9 +266,21 @@ _evas_canvas_eo_base_destructor(Eo *eo_e, Evas_Public_Data *e)
ERR("obj(%p, %s) ref count(%d) is bigger than 0. This object couldn't be deleted", o, o->type, eo_ref_get(o->object));
continue;
}
+ else
+ {
+ unrefs = eina_list_append(unrefs, o->object);
+ }
del = EINA_TRUE;
}
}
+ EINA_LIST_FREE(unrefs, eo_obj)
+ {
+ ERR("Killing Zombie Object [%p] ref=%i:%i\n", eo_obj, eo_ref_get(eo_obj), ___eo_ref2_get(eo_obj));
+ ___eo_ref2_reset(eo_obj);
+ while (eo_ref_get(eo_obj) > 1) eo_unref(eo_obj);
+ while (eo_ref_get(eo_obj) < 1) eo_ref(eo_obj);
+ eo_del(eo_obj);
+ }
}
}
EINA_INLIST_FOREACH(e->layers, lay)