group: Track calls to group_del
authorJean-Philippe Andre <jp.andre@samsung.com>
Wed, 15 Feb 2017 11:07:11 +0000 (20:07 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Wed, 15 Feb 2017 11:11:22 +0000 (20:11 +0900)
After a long search I found that fileselector was not calling
super.group_del on deletion, leading to the use of dangling pointers.
So let's verify that group_del is properly called.

See T4598

src/lib/edje/edje_smart.c
src/lib/elementary/elm_widget.c
src/lib/emotion/emotion_smart.c
src/lib/evas/canvas/efl_canvas_group.eo
src/lib/evas/canvas/evas_object_smart.c
src/lib/evas/canvas/evas_object_smart_clipped.c
src/lib/evas/include/evas_private.h

index 583e714..7af25b9 100644 (file)
@@ -159,6 +159,7 @@ _edje_object_efl_canvas_group_group_del(Eo *obj, Edje *ed)
    _edje_clean_objects(ed);
    _edje_unref(ed);
    _edje_lib_unref();
+   efl_canvas_group_del(efl_super(obj, MY_CLASS));
 }
 
 EOLIAN static void
index dd459bb..a070c4c 100644 (file)
@@ -486,6 +486,7 @@ _elm_widget_efl_canvas_group_group_del(Eo *obj, Elm_Widget_Smart_Data *sd)
    eina_stringshare_del(sd->access_info);
    eina_stringshare_del(sd->accessible_name);
    evas_object_smart_data_set(obj, NULL);
+   efl_canvas_group_del(efl_super(obj, MY_CLASS));
 }
 
 static void
index 96f14da..42b5e35 100644 (file)
@@ -1967,7 +1967,6 @@ _efl_canvas_video_efl_canvas_group_group_add(Evas_Object *obj, Efl_Canvas_Video_
 EOLIAN static void
 _efl_canvas_video_efl_canvas_group_group_del(Evas_Object *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
 {
-   if (!sd) return;
    if (sd->engine_instance)
      {
         emotion_engine_instance_file_close(sd->engine_instance);
@@ -1993,6 +1992,7 @@ _efl_canvas_video_efl_canvas_group_group_del(Evas_Object *obj EINA_UNUSED, Efl_C
    if (sd->smartobj) evas_object_smart_data_set(sd->smartobj, NULL);
    sd->smartobj = NULL;
    EINA_REFCOUNT_UNREF(sd) _smart_data_free(sd);
+   efl_canvas_group_del(efl_super(obj, MY_CLASS));
 }
 
 EOLIAN static void
index b28b5c9..2eda28e 100644 (file)
@@ -109,6 +109,7 @@ class Efl.Canvas.Group (Efl.Canvas.Object)
       class.constructor;
       class.destructor;
       Efl.Object.constructor;
+      Efl.Object.destructor;
       Efl.Canvas.Object.no_render { set; }
       Efl.Canvas.Object.paragraph_direction { get; set; }
    }
index 7238069..6450d2b 100644 (file)
@@ -49,6 +49,7 @@ struct _Evas_Smart_Data
    Eina_Bool         deletions_waiting : 1;
    Eina_Bool         need_recalculate : 1;
    Eina_Bool         update_boundingbox_needed : 1;
+   Eina_Bool         group_del_called : 1;
 };
 
 typedef struct
@@ -526,6 +527,7 @@ _efl_canvas_group_group_members_all_del(Evas_Object *eo_obj)
      {
         evas_object_del((Evas_Object *)((Evas_Object_Protected_Data *)memobj->object));
      }
+   o->group_del_called = EINA_TRUE;
 }
 
 static void
@@ -627,6 +629,17 @@ _efl_canvas_group_efl_object_constructor(Eo *eo_obj, Evas_Smart_Data *class_data
    return eo_obj;
 }
 
+EOLIAN static void
+_efl_canvas_group_efl_object_destructor(Eo *eo_obj, Evas_Smart_Data *o)
+{
+   efl_destructor(efl_super(eo_obj, MY_CLASS));
+   if (!o->group_del_called)
+     {
+        ERR("efl_canvas_group_del() was not called on this object: %p (%s)",
+            eo_obj, efl_class_name_get(eo_obj));
+     }
+}
+
 EAPI void
 evas_object_smart_move_children_relative(Eo *eo_obj, Evas_Coord dx, Evas_Coord dy)
 {
@@ -662,6 +675,7 @@ _efl_canvas_group_group_add(Eo *eo_obj, Evas_Smart_Data *o EINA_UNUSED)
 EOLIAN static void
 _efl_canvas_group_group_del(Eo *eo_obj EINA_UNUSED, Evas_Smart_Data *o EINA_UNUSED)
 {
+   o->group_del_called = EINA_TRUE;
 }
 
 EOLIAN static void
index 252709a..a4b96d3 100644 (file)
@@ -79,6 +79,7 @@ EOLIAN static void
 _efl_canvas_group_clipped_efl_canvas_group_group_del(Eo *eo_obj, Evas_Object_Smart_Clipped_Data *obj EINA_UNUSED)
 {
    evas_object_smart_clipped_smart_del(eo_obj);
+   // group_del_called was already set to true, no need to call super here.
 }
 
 static void
index 7360391..a62852a 100644 (file)
@@ -1674,7 +1674,7 @@ void *evas_object_smart_render_cache_get(const Evas_Object *eo_obj);
 void evas_object_smart_render_cache_set(Evas_Object *eo_obj, void *data);
 
 const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
-void _efl_canvas_group_group_members_all_del(Evas_Object *obj);
+void _efl_canvas_group_group_members_all_del(Evas_Object *eo_obj);
 void _evas_object_smart_xy_update(Eo *eo_obj, Evas_Coord *px, Evas_Coord *py, Evas_Coord x, Evas_Coord y);
 void evas_call_smarts_calculate(Evas *e);
 void evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj);