From: Seunghun Lee Date: Wed, 2 Sep 2020 21:07:20 +0000 (+0900) Subject: e_policy_visibility: Do not delete a job during executing jobs in a list. X-Git-Tag: submit/tizen/20200903.051822^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c1efeeddf74a5002623c5805f5e1f870dd889c8b;p=platform%2Fupstream%2Fenlightenment.git e_policy_visibility: Do not delete a job during executing jobs in a list. Deleting a E_Vis_Client could be happened while job has been executing by iterating list of job. In that situation, deleting a job and evaluating job list had list of job corrupted. So this patch marks a job deleted and lets it be deleted during job execution. Change-Id: I95059b9f61073a95212de2ca5c31b9127b8a0dcd --- diff --git a/src/bin/e_policy_visibility.c b/src/bin/e_policy_visibility.c index 880c502e18..0b2502ad8b 100644 --- a/src/bin/e_policy_visibility.c +++ b/src/bin/e_policy_visibility.c @@ -67,6 +67,8 @@ static E_Vis_Job_Group *pol_job_group = NULL; /* the head of list for E_Vis_Job_Group */ static Eina_Clist pol_job_group_head = EINA_CLIST_INIT(pol_job_group_head); +static Eina_Bool pol_job_exec_walking = EINA_FALSE; + static Eina_Inlist *_e_pol_vis_hooks[] = { [E_POL_VIS_HOOK_TYPE_FG_SET] = NULL, @@ -672,6 +674,15 @@ _e_vis_job_exec(Eina_Clist *elem) _e_vis_clist_unlink(elem); job = EINA_CLIST_ENTRY(elem, E_Vis_Job, entry); + if (job->deleted) + { + if ((job->type == E_VIS_JOB_TYPE_LOWER) || + (job->type == E_VIS_JOB_TYPE_HIDE) || + (job->type == E_VIS_JOB_TYPE_ICONIFY) || + (job->type == E_VIS_JOB_TYPE_LAYER_LOWER)) + e_comp_canvas_norender_pop(); + goto end; + } VS_INF(job->vc->ec, "EXEC JOB:%p, type:%d (is_del ec:%d)", job, job->type, e_object_is_del(E_OBJECT(job->vc->ec))); /* After calling the function below, ec may have been deleted. @@ -680,6 +691,8 @@ _e_vis_job_exec(Eina_Clist *elem) * to avoid segmentation fault error. */ _e_vis_client_job_exec(job->vc, job->type); + +end: INF("VISIBILITY | FREE JOB:%p, type:%d", job, job->type); E_FREE_FUNC(job->timer, ecore_timer_del); free(job); @@ -701,6 +714,7 @@ _e_vis_job_group_eval(E_Vis_Job_Group *group) EINA_CLIST_FOR_EACH_ENTRY_SAFE(job, tmp, &group->job_head, E_Vis_Job, entry) { + if (job->deleted) continue; if (_e_vis_client_is_grabbed(job->vc)) return EINA_FALSE; } @@ -714,6 +728,7 @@ _e_vis_job_group_state_update(E_Vis_Job_Group *group) EINA_CLIST_FOR_EACH_ENTRY_SAFE(job, tmp, &group->job_head, E_Vis_Job, entry) { + if (job->deleted) continue; if (_e_vis_client_is_uniconify_render_running_done(job->vc)) { job->vc->state = E_VIS_ICONIFY_STATE_UNICONIC; @@ -740,6 +755,7 @@ _e_vis_job_eval(void) _e_vis_job_queue_update(); + pol_job_exec_walking = EINA_TRUE; EINA_CLIST_FOR_EACH_ENTRY_SAFE(group, tmp, &pol_job_group_head, E_Vis_Job_Group, entry) { @@ -753,6 +769,8 @@ _e_vis_job_eval(void) /* execute all of job in the group */ _e_vis_job_group_exec(group); } + pol_job_exec_walking = EINA_FALSE; + INF("VISIBILITY | Job Eval End"); } @@ -807,14 +825,19 @@ _e_vis_job_del_by_client(E_Vis_Client *vc) &group->job_head, E_Vis_Job, entry) { if (job->vc != vc) continue; - _e_vis_job_del(&job->entry); + + if (pol_job_exec_walking) + job->deleted = EINA_TRUE; + else + _e_vis_job_del(&job->entry); } if (!eina_clist_empty(&group->job_head)) continue; _e_vis_job_group_del(&group->entry); } /* evaluate job list after deleting an element */ - _e_vis_job_eval(); + if (!pol_job_exec_walking) + _e_vis_job_eval(); } static E_Vis_Grab * diff --git a/src/bin/e_policy_visibility_internal.h b/src/bin/e_policy_visibility_internal.h index ae3ad346b6..17a3562574 100644 --- a/src/bin/e_policy_visibility_internal.h +++ b/src/bin/e_policy_visibility_internal.h @@ -163,6 +163,7 @@ struct _E_Vis_Job E_Vis_Client *vc; E_Vis_Job_Type type; Ecore_Timer *timer; + Eina_Bool deleted; }; #endif