e - e client, comp win etc. reffing fix ... part 2
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Mon, 15 Jun 2015 11:27:25 +0000 (20:27 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Mon, 15 Jun 2015 11:27:25 +0000 (20:27 +0900)
this follows 56cabf59c672af27af87eda82079de4e2ee2d38e then
4e5521b4d82063a2fbf6632a117fda201cc1687d where i have been trying to
fix a crash with e client and comp win references etc. i have gone
over all referencing with a fine tooth comb and found all the nigglies
i can., no leaks now, no crashes, no valgrind complaints etc. so i
call this fixed now. as best i know this is new in e20, so not a
backport fix

src/bin/e.h
src/bin/e_client.c
src/bin/e_comp.c
src/bin/e_comp_canvas.c
src/bin/e_comp_object.c
src/bin/e_comp_x.c
src/bin/e_exec.c
src/bin/e_remember.c

index d8afcef..d3fd409 100644 (file)
@@ -341,4 +341,31 @@ extern EINTERN double e_first_frame_start_time;
  * @}
  */
 
+#if 0
+#define REFD(obj, num) \
+   do { \
+      printf("%p <- %5i <- ref   | %s-%i\n", \
+             obj, E_OBJECT(obj)->references, \
+             __FILE__, num); \
+   } while (0)
+
+#define UNREFD(obj, num) \
+   do { \
+      printf("%p <- %5i <- unref | %s-%i\n", \
+             obj, E_OBJECT(obj)->references, \
+             __FILE__, num); \
+   } while (0)
+
+#define DELD(obj, num) \
+   do { \
+      printf("%p <- %5i <- del   | %s-%i\n", \
+             obj, E_OBJECT(obj)->references, \
+             __FILE__, num); \
+   } while (0)
+#else
+# define REFD(obj, num)
+# define UNREFD(obj, num)
+# define DELD(obj, num)
+#endif
+
 #endif
index 7f01963..e600e39 100644 (file)
@@ -175,6 +175,7 @@ _e_client_cb_drag_finished(E_Drag *drag, int dropped EINA_UNUSED)
    E_Client *ec;
 
    ec = drag->data;
+   UNREFD(ec, 1);
    e_object_unref(E_OBJECT(ec));
    client_drag = NULL;
 }
@@ -328,6 +329,7 @@ _e_client_hook_call(E_Client_Hook_Point hookpoint, E_Client *ec)
 static void
 _e_client_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
 {
+   UNREFD(ev->ec, 3);
    e_object_unref(E_OBJECT(ev->ec));
    free(ev);
 }
@@ -339,6 +341,7 @@ _e_client_event_simple(E_Client *ec, int type)
 
    ev = E_NEW(E_Event_Client, 1);
    ev->ec = ec;
+   REFD(ec, 3);
    e_object_ref(E_OBJECT(ec));
    ecore_event_add(type, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
 }
@@ -351,6 +354,7 @@ _e_client_event_property(E_Client *ec, int prop)
    ev = E_NEW(E_Event_Client_Property, 1);
    ev->ec = ec;
    ev->property = prop;
+   REFD(ec, 33);
    e_object_ref(E_OBJECT(ec));
    ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev, (Ecore_End_Cb)_e_client_event_simple_free, NULL);
 }
@@ -358,6 +362,7 @@ _e_client_event_property(E_Client *ec, int prop)
 static void
 _e_client_event_desk_set_free(void *d EINA_UNUSED, E_Event_Client_Desk_Set *ev)
 {
+   UNREFD(ev->ec, 4);
    e_object_unref(E_OBJECT(ev->ec));
    e_object_unref(E_OBJECT(ev->desk));
    free(ev);
@@ -366,6 +371,7 @@ _e_client_event_desk_set_free(void *d EINA_UNUSED, E_Event_Client_Desk_Set *ev)
 static void
 _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev)
 {
+   UNREFD(ev->ec, 5);
    e_object_unref(E_OBJECT(ev->ec));
    e_object_unref(E_OBJECT(ev->zone));
    free(ev);
@@ -439,6 +445,7 @@ _e_client_free(E_Client *ec)
    e_comp_object_redirected_set(ec->frame, 0);
    e_comp_object_render_update_del(ec->frame);
 
+   E_OBJECT(ec)->references++;
    if (ec->fullscreen)
      {
         ec->desk->fullscreen_clients = eina_list_remove(ec->desk->fullscreen_clients, ec);
@@ -531,7 +538,6 @@ _e_client_free(E_Client *ec)
    raise_stack = eina_list_remove(raise_stack, ec);
 
    e_hints_client_list_set();
-   evas_object_del(ec->frame);
    if (ec->e.state.profile.wait_desk)
      {
         e_object_delfn_del(E_OBJECT(ec->e.state.profile.wait_desk),
@@ -540,6 +546,8 @@ _e_client_free(E_Client *ec)
         e_object_unref(E_OBJECT(ec->e.state.profile.wait_desk));
      }
    ec->e.state.profile.wait_desk = NULL;
+   evas_object_del(ec->frame);
+   E_OBJECT(ec)->references--;
    free(ec);
 }
 
@@ -2664,6 +2672,7 @@ e_client_desk_set(E_Client *ec, E_Desk *desk)
      {
         ev = E_NEW(E_Event_Client_Desk_Set, 1);
         ev->ec = ec;
+        UNREFD(ec, 4);
         e_object_ref(E_OBJECT(ec));
         ev->desk = old_desk;
         e_object_ref(E_OBJECT(old_desk));
@@ -2949,6 +2958,7 @@ e_client_mouse_move(E_Client *ec, Evas_Point *output)
                        int x, y, w, h;
                        const char *drag_types[] = { "enlightenment/border" };
 
+                       REFD(ec, 1);
                        e_object_ref(E_OBJECT(ec));
                        e_comp_object_frame_icon_geometry_get(ec->frame, &x, &y, &w, &h);
 
@@ -3119,6 +3129,7 @@ e_client_zone_set(E_Client *ec, E_Zone *zone)
 
    ev = E_NEW(E_Event_Client_Zone_Set, 1);
    ev->ec = ec;
+   REFD(ec, 5);
    e_object_ref(E_OBJECT(ec));
    ev->zone = zone;
    e_object_ref(E_OBJECT(zone));
index 2b8e482..8290fb6 100644 (file)
@@ -374,6 +374,7 @@ _e_comp_cb_update(void)
         if (_e_comp_client_update(ec))
           {
              e_comp->post_updates = eina_list_append(e_comp->post_updates, ec);
+             REFD(ec, 111);
              e_object_ref(E_OBJECT(ec));
           }
      }
@@ -1294,7 +1295,10 @@ e_comp_shutdown(void)
 #endif
    E_FREE_FUNC(action_timeout, ecore_timer_del);
    while (e_comp->clients)
-     e_object_del(eina_list_data_get(e_comp->clients));
+     {
+        DELD(eina_list_data_get(e_comp->clients), 99999);
+        e_object_del(eina_list_data_get(e_comp->clients));
+     }
    e_object_del(E_OBJECT(e_comp));
    E_FREE_LIST(handlers, ecore_event_handler_del);
    E_FREE_LIST(actions, e_object_del);
index 736993b..70f6101 100644 (file)
@@ -53,6 +53,7 @@ _e_comp_canvas_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *ev
         //INF("POST %p", ec);
         if (!e_object_is_del(E_OBJECT(ec)))
           e_pixmap_image_clear(ec->pixmap, 1);
+        UNREFD(ec, 111);
         e_object_unref(E_OBJECT(ec));
      }
 }
index 665952e..31dc7f6 100644 (file)
@@ -147,7 +147,11 @@ _e_comp_object_event_free(void *d EINA_UNUSED, void *event)
    E_Client *ec;
 
    ec = evas_object_data_get(ev->comp_object, "E_Client");
-   if (ec) e_object_unref(E_OBJECT(ec));
+   if (ec)
+     {
+        UNREFD(ec, 1);
+        e_object_unref(E_OBJECT(ec));
+     }
    evas_object_unref(ev->comp_object);
    free(ev);
 }
@@ -163,7 +167,11 @@ _e_comp_object_event_add(Evas_Object *obj)
    evas_object_ref(obj);
    ev->comp_object = obj;
    ec = evas_object_data_get(ev->comp_object, "E_Client");
-   if (ec) e_object_ref(E_OBJECT(ec));
+   if (ec)
+     {
+        REFD(ec, 1);
+        e_object_ref(E_OBJECT(ec));
+     }
    ecore_event_add(E_EVENT_COMP_OBJECT_ADD, ev, _e_comp_object_event_free, NULL);
 }
 
@@ -647,26 +655,46 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw)
 
 /////////////////////////////////////////////
 
-/* handle the end of a compositor animation */
 static void
-_e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
+_e_comp_object_animating_begin(E_Comp_Object *cw)
 {
-   E_Comp_Object *cw = data;
+   cw->animating++;
+   if (cw->animating == 1)
+     {
+        e_comp->animating++;
+        REFD(cw->ec, 2);
+        e_object_ref(E_OBJECT(cw->ec));
+     }
+}
 
-   //INF("DONE DEFER %p: %dx%d - %s", cw->ec, cw->w, cw->h, emission);
-   /* visible clients which have never been sized are a bug */
-   if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
-     CRI("ACK!");
+static Eina_Bool
+_e_comp_object_animating_end(E_Comp_Object *cw)
+{
    if (cw->animating)
      {
         cw->animating--;
         if (!cw->animating)
           {
              e_comp->animating--;
+             UNREFD(cw->ec, 2);
              /* remove ref from animation start, account for possibility of deletion from unref */
-             if (!e_object_unref(E_OBJECT(cw->ec))) return;
+             return e_object_unref(E_OBJECT(cw->ec));
           }
      }
+   return EINA_TRUE;
+}
+
+/* handle the end of a compositor animation */
+static void
+_e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
+{
+   E_Comp_Object *cw = data;
+
+   //INF("DONE DEFER %p: %dx%d - %s", cw->ec, cw->w, cw->h, emission);
+   /* visible clients which have never been sized are a bug */
+   if ((!cw->ec->new_client) && (!cw->ec->changes.size) && ((cw->w < 0) || (cw->h < 0)) && (!strcmp(emission, "e,action,show,done")))
+     CRI("ACK!");
+   if (!_e_comp_object_animating_end(cw)) return;
    if (cw->animating) return;
    /* hide only after animation finishes to guarantee a full run of the animation */
    if (cw->defer_hide && ((!strcmp(emission, "e,action,hide,done")) || (!strcmp(emission, "e,action,done"))))
@@ -1298,21 +1326,10 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj)
              else
                {
                   e_comp_object_signal_emit(obj, "e,state,hidden", "e");
-                  cw->animating++;
-                  if (cw->animating == 1)
-                    {
-                       e_comp->animating++;
-                       e_object_ref(E_OBJECT(cw->ec));
-                    }
+                  _e_comp_object_animating_begin(cw);
                   if (cw->visibility_effect)
                     {
-                       cw->animating++;
-// same as above, but unreachable
-//                       if (cw->animating == 1)
-//                         {
-//                            e_comp->animating++;
-//                            e_object_ref(E_OBJECT(cw->ec));
-//                         }
+                       _e_comp_object_animating_begin(cw);
                        e_comp_object_effect_set(obj, cw->visibility_effect);
                        e_comp_object_effect_params_set(obj, 0, (int[]){0}, 1);
                        e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw);
@@ -2049,21 +2066,10 @@ _e_comp_smart_show(Evas_Object *obj)
    else
      {
         e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e");
-        cw->animating++;
-        if (cw->animating == 1)
-          {
-             e_comp->animating++;
-             e_object_ref(E_OBJECT(cw->ec));
-          }
+        _e_comp_object_animating_begin(cw);
         if (cw->visibility_effect)
           {
-             cw->animating++;
-// same logic as above but unreachable
-//             if (cw->animating == 1)
-//               {
-//                  e_comp->animating++;
-//                  e_object_ref(E_OBJECT(cw->ec));
-//               }
+             _e_comp_object_animating_begin(cw);
              e_comp_object_effect_set(obj, cw->visibility_effect);
              e_comp_object_effect_params_set(obj, 0, (int[]){1}, 1);
              e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw);
@@ -2084,16 +2090,9 @@ _e_comp_smart_del(Evas_Object *obj)
 
    INTERNAL_ENTRY;
 
-   if (cw->animating)
-     {
-        e_comp->animating--;
-        e_object_unref(E_OBJECT(cw->ec));
-     }
-   cw->animating = 0;
+   e_comp_object_render_update_del(cw->smart_obj);
    E_FREE_FUNC(cw->updates, eina_tiler_free);
    E_FREE_FUNC(cw->pending_updates, eina_tiler_free);
-   DBG("  [%p] del", cw->ec);
-   e_comp_object_render_update_del(cw->smart_obj);
 
    if (cw->obj_mirror)
      {
@@ -2121,6 +2120,15 @@ _e_comp_smart_del(Evas_Object *obj)
    e_comp_shape_queue();
    eina_stringshare_del(cw->frame_theme);
    eina_stringshare_del(cw->frame_name);
+   if (cw->animating)
+     {
+        cw->animating = 0;
+        e_comp->animating--;
+        UNREFD(cw->ec, 2);
+        e_object_unref(E_OBJECT(cw->ec));
+     }
+//   UNREFD(cw->ec, 9);
+//   e_object_unref(E_OBJECT(cw->ec));
    free(cw);
 }
 
@@ -2542,6 +2550,8 @@ e_comp_object_client_add(E_Client *ec)
    o = evas_object_smart_add(e_comp->evas, _e_comp_smart);
    cw = evas_object_smart_data_get(o);
    evas_object_data_set(o, "E_Client", ec);
+//   REFD(ec, 9);
+//   e_object_ref(E_OBJECT(ec));
    cw->ec = ec;
    ec->frame = o;
    evas_object_data_set(o, "comp_object", (void*)1);
@@ -3411,6 +3421,7 @@ e_comp_object_render(Evas_Object *obj)
                     e_comp_object_damage(obj, 0, 0, pw, ph);
                   else
                     {
+                       DELD(cw->ec, 2);
                        e_object_del(E_OBJECT(cw->ec));
                        return EINA_FALSE;
                     }
@@ -3444,6 +3455,7 @@ e_comp_object_render(Evas_Object *obj)
                e_comp_object_damage(obj, 0, 0, pw, ph);
              else
                {
+                  DELD(cw->ec, 3);
                   e_object_del(E_OBJECT(cw->ec));
                   return EINA_FALSE;
                }
@@ -3591,16 +3603,8 @@ _e_comp_object_effect_end_cb(void *data, Evas_Object *obj, const char *emission,
    E_Comp_Object *cw = data;
 
    edje_object_signal_callback_del_full(obj, "e,action,done", "e", _e_comp_object_effect_end_cb, NULL);
-   if (cw->animating)
-     {
-        cw->animating--;
-        if (!cw->animating)
-          {
-             e_comp->animating--;
-             if (e_object_unref(E_OBJECT(cw->ec))) e_comp_shape_queue();
-          }
-     }
-
+   if (!_e_comp_object_animating_end(cw)) return;
+   e_comp_shape_queue();
    end_cb = evas_object_data_get(obj, "_e_comp.end_cb");
    if (!end_cb) return;
    end_data = evas_object_data_get(obj, "_e_comp.end_data");
@@ -3645,13 +3649,7 @@ e_comp_object_effect_start(Evas_Object *obj, Edje_Signal_Cb end_cb, const void *
 
    edje_object_signal_emit(cw->effect_obj, "e,action,go", "e");
    if (cw->animating) return;
-   cw->animating++;
-// same standard logic but useless here
-//   if (cw->animating == 1)
-//     {
-        e_comp->animating++;
-        e_object_ref(E_OBJECT(cw->ec));
-//     }
+   _e_comp_object_animating_begin(cw);
 }
 
 /* stop a currently-running effect immediately */
@@ -3668,15 +3666,7 @@ e_comp_object_effect_stop(Evas_Object *obj, Edje_Signal_Cb end_cb)
      }
    edje_object_signal_emit(cw->effect_obj, "e,action,stop", "e");
    edje_object_signal_callback_del_full(cw->effect_obj, "e,action,done", "e", _e_comp_object_effect_end_cb, cw);
-   if (cw->animating)
-     {
-        cw->animating--;
-        if (!cw->animating)
-          {
-             e_comp->animating--;
-             e_object_unref(E_OBJECT(cw->ec));
-          }
-     }
+   _e_comp_object_animating_end(cw);
 }
 
 static int
index 6f77a0b..a6f2d36 100644 (file)
@@ -101,6 +101,7 @@ _e_comp_x_client_event_free(void *d EINA_UNUSED, void *e)
 {
    E_Event_Client *ev = e;
 
+   UNREFD(ev->ec, 1);
    e_object_unref(E_OBJECT(ev->ec));
    free(ev);
 }
@@ -166,12 +167,14 @@ _e_comp_x_client_new_helper(E_Client *ec)
    if (!ecore_x_window_attributes_get(win, &ec->comp_data->initial_attributes))
      {
         //CRI("OUCH! FIX THIS!");
+        DELD(ec, 1);
         e_object_del(E_OBJECT(ec));
         return EINA_FALSE;
      }
    if (ec->re_manage && (!ec->comp_data->initial_attributes.visible))
      {
         /* ain't gonna be no hidden clients on my watch! */
+        DELD(ec, 1);
         e_object_del(E_OBJECT(ec));
         return EINA_FALSE;
      }
@@ -188,6 +191,7 @@ _e_comp_x_client_new_helper(E_Client *ec)
      {
         /* this is the ecore-x private window :/ */
         e_comp_ignore_win_add(E_PIXMAP_TYPE_X, win);
+        DELD(ec, 1);
         e_object_del(E_OBJECT(ec));
         return EINA_FALSE;
      }
@@ -1032,6 +1036,7 @@ _e_comp_x_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Wi
         evas_object_pass_events_set(ec->frame, 1);
         evas_object_hide(ec->frame);
         ec->comp_data->deleted = 1;
+        DELD(ec, 2);
         e_object_del(E_OBJECT(ec));
      }
    return ECORE_CALLBACK_PASS_ON;
@@ -1294,6 +1299,7 @@ _e_comp_x_hide(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Windo
           {
              if (ec->exe_inst && ec->exe_inst->exe)
                ec->exe_inst->phony = 0;
+             DELD(ec, 3);
              e_object_del(E_OBJECT(ec));
           }
      }
@@ -3040,6 +3046,7 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, E_Client *ec)
 
            ev = E_NEW(E_Event_Client_Property, 1);
            ev->ec = ec;
+           REFD(ec, 1);
            e_object_ref(E_OBJECT(ec));
            ev->property = E_CLIENT_PROPERTY_NETWM_STATE;
            ecore_event_add(E_EVENT_CLIENT_PROPERTY, ev, _e_comp_x_client_event_free, NULL);
@@ -4722,7 +4729,10 @@ _e_comp_x_manage_windows(void)
              ec = _e_comp_x_client_new(windows[i], 1);
           }
         if (ec && (!ec->comp_data->initial_attributes.visible))
-          E_FREE_FUNC(ec, e_object_del);
+          {
+             DELD(ec, 3);
+             E_FREE_FUNC(ec, e_object_del);
+          }
         if (ec)
           {
              if (ec->override)
index d538a0f..c6c78f2 100644 (file)
@@ -359,8 +359,9 @@ e_exec_instance_found(E_Exec_Instance *inst)
 E_API void
 e_exec_instance_client_add(E_Exec_Instance *inst, E_Client *ec)
 {
-   e_object_ref(E_OBJECT(ec));
    inst->clients = eina_list_append(inst->clients, ec);
+   REFD(ec, 2);
+   e_object_ref(E_OBJECT(ec));
    ec->exe_inst = inst;
    inst->ref++;
    ecore_event_add(E_EVENT_EXEC_NEW_CLIENT, inst, _e_exec_cb_exec_new_client_free, ec);
@@ -660,7 +661,6 @@ _e_exec_instance_free(E_Exec_Instance *inst)
    if (!inst->deleted)
      {
         inst->deleted = 1;
-        E_LIST_FOREACH(inst->clients, e_object_ref);
         ecore_event_add(E_EVENT_EXEC_DEL, inst, _e_exec_cb_exec_del_free, inst);
         return;
      }
@@ -671,7 +671,6 @@ _e_exec_instance_free(E_Exec_Instance *inst)
    EINA_LIST_FREE(inst->clients, ec)
      {
         ec->exe_inst = NULL;
-        e_object_unref(E_OBJECT(ec));
      }
    if (inst->desktop) efreet_desktop_free(inst->desktop);
    if (!inst->phony)
@@ -694,10 +693,12 @@ static void
 _e_exec_cb_exec_new_client_free(void *data, void *ev)
 {
    E_Exec_Instance *inst = ev;
+   E_Client *ec = data;
 
    inst->ref--;
    _e_exec_instance_free(inst);
-   e_object_unref(data);
+   UNREFD(ec, 1);
+   e_object_unref(E_OBJECT(ec));
 }
 
 static void
index 4651703..cf9d63c 100644 (file)
@@ -387,6 +387,7 @@ static void
 _e_remember_event_free(void *d EINA_UNUSED, void *event)
 {
    E_Event_Remember_Update *ev = event;
+   printf("unref10: %p\n", ev->ec);
    e_object_unref(E_OBJECT(ev->ec));
    free(ev);
 }
@@ -493,6 +494,7 @@ _e_remember_update(E_Client *ec, E_Remember *rem)
       ev = malloc(sizeof(E_Event_Remember_Update));
       if (!ev) return;
       ev->ec = ec;
+      printf("ref10: %p\n", ec);
       e_object_ref(E_OBJECT(ec));
       ecore_event_add(E_EVENT_REMEMBER_UPDATE, ev, _e_remember_event_free, NULL);
    }