e - e client, comp win etc. reffing fix ... part 2

this follows 56cabf59c6 then
4e5521b4d8 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
This commit is contained in:
Carsten Haitzler 2015-06-15 20:27:25 +09:00
parent 56cabf59c6
commit 6b64e40122
8 changed files with 125 additions and 79 deletions

View 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

View 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));

View 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);

View 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));
}
}

View 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,6 +655,35 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw)
/////////////////////////////////////////////
static void
_e_comp_object_animating_begin(E_Comp_Object *cw)
{
cw->animating++;
if (cw->animating == 1)
{
e_comp->animating++;
REFD(cw->ec, 2);
e_object_ref(E_OBJECT(cw->ec));
}
}
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 */
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)
@ -657,16 +694,7 @@ _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *
/* 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 (cw->animating)
{
cw->animating--;
if (!cw->animating)
{
e_comp->animating--;
/* remove ref from animation start, account for possibility of deletion from unref */
if (!e_object_unref(E_OBJECT(cw->ec))) return;
}
}
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

View 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)

View 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

View 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);
}