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)
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 293234a..f72ee69 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
1132/** 1132/**
1133 * @} 1133 * @}
1134 */ 1134 */
1135
1136
1137 /* Private for EFL internal use only. Do not use these! */
1138EAPI int ___eo_ref2_get(const Eo *obj_id);
1139EAPI void ___eo_ref2_reset(const Eo *obj_id);
1140
1135#ifdef __cplusplus 1141#ifdef __cplusplus
1136} 1142}
1137#endif 1143#endif
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index a7df2b5..0690c44 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -1479,6 +1479,22 @@ eo_ref_get(const Eo *obj_id)
1479 return obj->user_refcount; 1479 return obj->user_refcount;
1480} 1480}
1481 1481
1482EAPI int
1483___eo_ref2_get(const Eo *obj_id)
1484{
1485 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, 0);
1486
1487 return obj->refcount;
1488}
1489
1490EAPI void
1491___eo_ref2_reset(const Eo *obj_id)
1492{
1493 EO_OBJ_POINTER_RETURN(obj_id, obj);
1494 obj->refcount = 0;
1495}
1496
1497
1482EAPI void 1498EAPI void
1483eo_del_intercept_set(Eo *obj_id, Eo_Del_Intercept del_intercept_func) 1499eo_del_intercept_set(Eo *obj_id, Eo_Del_Intercept del_intercept_func)
1484{ 1500{
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index 7f7afa2..44959b3 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)
251 del = EINA_FALSE; 251 del = EINA_FALSE;
252 EINA_INLIST_FOREACH(e->layers, lay) 252 EINA_INLIST_FOREACH(e->layers, lay)
253 { 253 {
254 Eo *eo_obj;
254 Evas_Object_Protected_Data *o; 255 Evas_Object_Protected_Data *o;
256 Eina_List *unrefs = NULL;
255 257
256 evas_layer_pre_free(lay); 258 evas_layer_pre_free(lay);
257 259
@@ -264,9 +266,21 @@ _evas_canvas_eo_base_destructor(Eo *eo_e, Evas_Public_Data *e)
264 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)); 266 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));
265 continue; 267 continue;
266 } 268 }
269 else
270 {
271 unrefs = eina_list_append(unrefs, o->object);
272 }
267 del = EINA_TRUE; 273 del = EINA_TRUE;
268 } 274 }
269 } 275 }
276 EINA_LIST_FREE(unrefs, eo_obj)
277 {
278 ERR("Killing Zombie Object [%p] ref=%i:%i\n", eo_obj, eo_ref_get(eo_obj), ___eo_ref2_get(eo_obj));
279 ___eo_ref2_reset(eo_obj);
280 while (eo_ref_get(eo_obj) > 1) eo_unref(eo_obj);
281 while (eo_ref_get(eo_obj) < 1) eo_ref(eo_obj);
282 eo_del(eo_obj);
283 }
270 } 284 }
271 } 285 }
272 EINA_INLIST_FOREACH(e->layers, lay) 286 EINA_INLIST_FOREACH(e->layers, lay)