e_policy_visibility: Do not delete a job during executing jobs in a list. 20/243020/2 accepted/tizen/unified/20200903.151707 submit/tizen/20200903.051822
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 2 Sep 2020 21:07:20 +0000 (06:07 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Thu, 3 Sep 2020 04:51:12 +0000 (04:51 +0000)
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

src/bin/e_policy_visibility.c
src/bin/e_policy_visibility_internal.h

index 880c502e18de4bf8e771bbb92b7b5e660ccb08cc..0b2502ad8b22c2f983881dbd73205701fc3fc9a3 100644 (file)
@@ -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 *
index ae3ad346b638ac189eaaf3c5c955474f433fb6ba..17a3562574d878ac91142e161185720b8e651c09 100644 (file)
@@ -163,6 +163,7 @@ struct _E_Vis_Job
    E_Vis_Client   *vc;
    E_Vis_Job_Type  type;
    Ecore_Timer    *timer;
+   Eina_Bool       deleted;
 };
 
 #endif