forked from enlightenment/efl
edje crash with run program references - fix
i found a crash today where a heme could cause a crash if it just did the right things. the run program was freed while still being accessed. so add some ref counting to keep it alive until references go to 0. and add soem refs while we store it in lists. @fix
This commit is contained in:
parent
fb153fc57a
commit
7b59a4851e
|
@ -387,35 +387,51 @@ _edje_timer_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
|||
_edje_util_freeze(ed);
|
||||
if ((!ed->paused) && (!ed->delete_me))
|
||||
{
|
||||
const void *tmp;
|
||||
Edje_Running_Program *tmp;
|
||||
|
||||
ed->walking_actions = EINA_TRUE;
|
||||
EINA_LIST_FOREACH(ed->actions, l, tmp)
|
||||
newl = eina_list_append(newl, tmp);
|
||||
{
|
||||
tmp->ref++;
|
||||
newl = eina_list_append(newl, tmp);
|
||||
}
|
||||
while (newl)
|
||||
{
|
||||
Edje_Running_Program *runp;
|
||||
|
||||
runp = eina_list_data_get(newl);
|
||||
newl = eina_list_remove(newl, eina_list_data_get(newl));
|
||||
runp->ref--;
|
||||
if (!runp->delete_me)
|
||||
_edje_program_run_iterate(runp, t);
|
||||
if (_edje_block_break(ed))
|
||||
{
|
||||
eina_list_free(newl);
|
||||
EINA_LIST_FREE(newl, tmp)
|
||||
{
|
||||
tmp->ref--;
|
||||
if ((tmp->delete_me) && (tmp->ref == 0))
|
||||
{
|
||||
_edje_program_run_cleanup(ed, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
newl = NULL;
|
||||
goto break_prog;
|
||||
}
|
||||
}
|
||||
EINA_LIST_FOREACH(ed->actions, l, tmp)
|
||||
newl = eina_list_append(newl, tmp);
|
||||
{
|
||||
tmp->ref++;
|
||||
newl = eina_list_append(newl, tmp);
|
||||
}
|
||||
while (newl)
|
||||
{
|
||||
Edje_Running_Program *runp;
|
||||
|
||||
runp = eina_list_data_get(newl);
|
||||
newl = eina_list_remove(newl, eina_list_data_get(newl));
|
||||
if (runp->delete_me)
|
||||
runp->ref--;
|
||||
if ((runp->delete_me) && (runp->ref == 0))
|
||||
{
|
||||
_edje_program_run_cleanup(ed, runp);
|
||||
free(runp);
|
||||
|
|
|
@ -2059,6 +2059,7 @@ struct _Edje_Running_Program
|
|||
Edje *edje;
|
||||
Edje_Program *program;
|
||||
double start_time;
|
||||
unsigned short ref;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
|
|
|
@ -299,20 +299,32 @@ _edje_object_animation_set(Eo *obj, Edje *ed, Eina_Bool on)
|
|||
if (!on)
|
||||
{
|
||||
Eina_List *newl = NULL;
|
||||
const void *data;
|
||||
Edje_Running_Program *data;
|
||||
|
||||
EINA_LIST_FOREACH(ed->actions, l, data)
|
||||
newl = eina_list_append(newl, data);
|
||||
{
|
||||
data->ref++;
|
||||
newl = eina_list_append(newl, data);
|
||||
}
|
||||
while (newl)
|
||||
{
|
||||
Edje_Running_Program *runp;
|
||||
|
||||
runp = eina_list_data_get(newl);
|
||||
newl = eina_list_remove(newl, eina_list_data_get(newl));
|
||||
runp->ref--;
|
||||
_edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time));
|
||||
if (_edje_block_break(ed))
|
||||
{
|
||||
eina_list_free(newl);
|
||||
EINA_LIST_FREE(newl, data)
|
||||
{
|
||||
data->ref--;
|
||||
if ((data->delete_me) && (data->ref == 0))
|
||||
{
|
||||
_edje_program_run_cleanup(ed, data);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
goto break_prog;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +446,14 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
|
|||
// _edje_emit(ed, "program,stop", runp->program->name);
|
||||
if (_edje_block_break(ed))
|
||||
{
|
||||
if (!ed->walking_actions) free(runp);
|
||||
if (!ed->walking_actions)
|
||||
{
|
||||
if (runp->ref == 0)
|
||||
{
|
||||
_edje_program_run_cleanup(ed, runp);
|
||||
free(runp);
|
||||
}
|
||||
}
|
||||
goto break_prog;
|
||||
}
|
||||
EINA_LIST_FOREACH(runp->program->after, l, pa)
|
||||
|
@ -447,14 +466,22 @@ _edje_program_run_iterate(Edje_Running_Program *runp, double tim)
|
|||
if (pr) _edje_program_run(ed, pr, 0, "", "");
|
||||
if (_edje_block_break(ed))
|
||||
{
|
||||
if (!ed->walking_actions) free(runp);
|
||||
if ((!ed->walking_actions) && (runp->ref == 0))
|
||||
{
|
||||
_edje_program_run_cleanup(ed, runp);
|
||||
free(runp);
|
||||
}
|
||||
goto break_prog;
|
||||
}
|
||||
}
|
||||
}
|
||||
_edje_util_thaw(ed);
|
||||
_edje_unref(ed);
|
||||
if (!ed->walking_actions) free(runp);
|
||||
if ((!ed->walking_actions) && (runp->ref == 0))
|
||||
{
|
||||
_edje_program_run_cleanup(ed, runp);
|
||||
free(runp);
|
||||
}
|
||||
_edje_unblock(ed);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
@ -513,7 +540,7 @@ _edje_program_end(Edje *ed, Edje_Running_Program *runp)
|
|||
// _edje_emit(ed, "program,stop", pname);
|
||||
_edje_util_thaw(ed);
|
||||
_edje_unref(ed);
|
||||
if (free_runp) free(runp);
|
||||
if ((free_runp) && (runp->ref == 0)) free(runp);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPHYSICS
|
||||
|
|
Loading…
Reference in New Issue