e_keyrouter: protect key grab list while traversing list 74/300874/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Thu, 2 Nov 2023 12:35:11 +0000 (21:35 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Fri, 3 Nov 2023 06:24:30 +0000 (15:24 +0900)
Change-Id: I0735dadc932d2b0733ffbaf9985e4bcd4625d0b9
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/e_keyrouter.c
src/bin/e_keyrouter_events.c
src/bin/e_keyrouter_list.c
src/bin/e_keyrouter_private.h
src/bin/e_keyrouter_wl.c

index 2f4e11e..975dcff 100644 (file)
@@ -422,7 +422,7 @@ _e_keyrouter_query_tizen_key_table(void)
    krt->HardKeys = E_NEW(E_Keyrouter_Grabbed_Key, kconf->max_keycode + 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(krt->HardKeys, EINA_FALSE);
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
 
    krt->numTizenHWKeys = kconf->num_keycode;
    krt->max_tizen_hwkeys = kconf->max_keycode;
@@ -459,7 +459,7 @@ _e_keyrouter_query_tizen_key_table(void)
           }
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    if (e_comp_wl_input_keymap_cache_file_use_get() == EINA_FALSE)
      {
@@ -674,7 +674,7 @@ e_keyrouter_init(void)
    if (e_input_thread_mode_get())
      g_mutex_init(&krt->event_handler_mutex);
 
-   g_mutex_init(&krt->grab_key_mutex);
+   g_rec_mutex_init(&krt->grab_key_mutex);
 
    kconfig = E_NEW(E_Keyrouter_Config_Data, 1);
    EINA_SAFETY_ON_NULL_GOTO(kconfig, err);
@@ -739,7 +739,7 @@ e_keyrouter_shutdown(void)
 
    _e_keyrouter_deinit_handlers();
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    for (i = 0; i <= krt->max_tizen_hwkeys; i++)
      {
         if (krt->HardKeys[i].keyname)
@@ -748,7 +748,7 @@ e_keyrouter_shutdown(void)
           E_FREE(keycode_data);
      }
    E_FREE(krt->HardKeys);
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    EINA_LIST_FREE(krt->ignore_list, keycode_data)
      E_FREE(keycode_data);
@@ -772,6 +772,8 @@ e_keyrouter_shutdown(void)
         krt->longkey.timer = 0;
      }
 
+   g_rec_mutex_clear(&krt->grab_key_mutex);
+
    e_keyrouter_wl_shutdown();
 
    E_FREE(krt);
index 39d1330..23403af 100644 (file)
@@ -13,11 +13,11 @@ static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int a
 static Eina_Bool
 _e_keyrouter_is_key_grabbed(int key)
 {
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
 
    if (!krt->HardKeys[key].keycode)
      {
-        g_mutex_unlock(&krt->grab_key_mutex);
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
         return EINA_FALSE;
      }
    if (krt->HardKeys[key].excl_ptr ||
@@ -25,11 +25,11 @@ _e_keyrouter_is_key_grabbed(int key)
         krt->HardKeys[key].top_ptr ||
         krt->HardKeys[key].shared_ptr)
      {
-        g_mutex_unlock(&krt->grab_key_mutex);
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
         return EINA_TRUE;
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    return EINA_FALSE;
 }
@@ -70,15 +70,15 @@ _e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type)
         return EINA_FALSE;
      }
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
 
    if (!krt->HardKeys[ev->keycode].keycode)
      {
-        g_mutex_unlock(&krt->grab_key_mutex);
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
         return EINA_FALSE;
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    return EINA_TRUE;
 }
@@ -183,10 +183,8 @@ _e_keyrouter_key_cancel(int keycode)
    E_FREE(keyname);
    EINA_SAFETY_ON_NULL_GOTO(key_release, failed);
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    press_ptr_list = krt->HardKeys[keycode].press_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
-
    EINA_LIST_FREE(press_ptr_list, key_node_data)
      {
         _e_keyrouter_key_send(ECORE_EVENT_KEY_DOWN, key_cancel, NULL, key_node_data);
@@ -204,9 +202,8 @@ _e_keyrouter_key_cancel(int keycode)
         E_FREE(key_node_data);
      }
 
-   g_mutex_lock(&krt->grab_key_mutex);
    krt->HardKeys[keycode].press_ptr = NULL;
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    _e_keyrouter_key_free(key_cancel);
    _e_keyrouter_key_free(key_release);
@@ -497,10 +494,8 @@ _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev)
 
    if (krt->isPictureOffEnabled == 1)
      {
-        g_mutex_lock(&krt->grab_key_mutex);
+        g_rec_mutex_lock(&krt->grab_key_mutex);
         Eina_List *pic_off_ptr_list = krt->HardKeys[keycode].pic_off_ptr;
-        g_mutex_unlock(&krt->grab_key_mutex);
-
         EINA_LIST_FOREACH(pic_off_ptr_list, l, key_node_data)
           {
              if (key_node_data)
@@ -517,6 +512,7 @@ _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev)
                   if(cmd) E_FREE(cmd);
                }
           }
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
         return;
      }
 
@@ -553,9 +549,8 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *de
    E_Keyrouter_Event_Data *key_data = NULL;
 
    /* Deliver release  clean up pressed key list */
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    Eina_List *press_ptr_list = krt->HardKeys[ev->keycode].press_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
    EINA_LIST_FREE(press_ptr_list, key_node_data)
      {
         if (key_node_data->focused == EINA_TRUE)
@@ -619,9 +614,8 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *de
 
         E_FREE(key_node_data);
      }
-   g_mutex_lock(&krt->grab_key_mutex);
    krt->HardKeys[ev->keycode].press_ptr = NULL;
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 }
 
 static void
@@ -649,9 +643,8 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
         return;
      }
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    Eina_List *excl_ptr_list = krt->HardKeys[keycode].excl_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH(excl_ptr_list, l, key_node_data)
      {
         if (key_node_data)
@@ -667,13 +660,14 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
                       key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
              if(pname) E_FREE(pname);
              if(cmd) E_FREE(cmd);
+             g_rec_mutex_unlock(&krt->grab_key_mutex);
              return;
           }
      }
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    Eina_List *or_excl_ptr = krt->HardKeys[keycode].or_excl_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH(or_excl_ptr, l, key_node_data)
      {
         if (key_node_data)
@@ -689,16 +683,17 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
                      key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
              if(pname) E_FREE(pname);
              if(cmd) E_FREE(cmd);
+             g_rec_mutex_unlock(&krt->grab_key_mutex);
              return;
           }
      }
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    // Top position grab must need a focus surface.
    if (surface_focus)
      {
-        g_mutex_lock(&krt->grab_key_mutex);
+        g_rec_mutex_lock(&krt->grab_key_mutex);
         Eina_List *top_ptr_list = krt->HardKeys[keycode].top_ptr;
-        g_mutex_unlock(&krt->grab_key_mutex);
         EINA_LIST_FOREACH(top_ptr_list, l, key_node_data)
           {
              if (key_node_data)
@@ -717,6 +712,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
 
                        if(pname) E_FREE(pname);
                        if(cmd) E_FREE(cmd);
+                       g_rec_mutex_unlock(&krt->grab_key_mutex);
                        return;
                     }
                   krt->isWindowStackChanged = EINA_FALSE;
@@ -736,17 +732,19 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
 
                        if(pname) E_FREE(pname);
                        if(cmd) E_FREE(cmd);
+                       g_rec_mutex_unlock(&krt->grab_key_mutex);
                        return;
                     }
                   break;
                }
           }
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
        goto need_shared;
      }
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    shared_ptr_list = krt->HardKeys[keycode].shared_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    if (shared_ptr_list)
      {
@@ -762,9 +760,8 @@ need_shared:
           }
         if (res)
           {
-             g_mutex_lock(&krt->grab_key_mutex);
+             g_rec_mutex_lock(&krt->grab_key_mutex);
              shared_ptr_list = krt->HardKeys[keycode].shared_ptr;
-             g_mutex_unlock(&krt->grab_key_mutex);
              EINA_LIST_FOREACH(shared_ptr_list, l, key_node_data)
                {
                   if (key_node_data)
@@ -788,6 +785,7 @@ need_shared:
                          }
                     }
                }
+             g_rec_mutex_unlock(&krt->grab_key_mutex);
           }
      }
 }
@@ -870,25 +868,25 @@ _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
           }
 
         /* TODO: Check this client is located inside a display boundary */
-        g_mutex_lock(&krt->grab_key_mutex);
+        g_rec_mutex_lock(&krt->grab_key_mutex);
         Eina_List *top_ptr_list = krt->HardKeys[arr_idx].top_ptr;
-        g_mutex_unlock(&krt->grab_key_mutex);
         EINA_LIST_FOREACH_SAFE(top_ptr_list, l, l_next, key_node_data)
           {
              if (key_node_data)
                {
                   if (ec_top == e_client_from_surface_resource(key_node_data->surface))
                     {
-                       g_mutex_lock(&krt->grab_key_mutex);
                        krt->HardKeys[arr_idx].top_ptr = eina_list_promote_list(krt->HardKeys[arr_idx].top_ptr, l);
-                       g_mutex_unlock(&krt->grab_key_mutex);
                        KLDBG("Move a client(e_client: %p, wl_surface: %p) to first index of list(key: %d)",
                                 ec_top, key_node_data->surface, arr_idx);
+                       g_rec_mutex_unlock(&krt->grab_key_mutex);
                        return EINA_TRUE;
                     }
                }
           }
 
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
+
         if (ec_top == ec_focus)
           {
              KLDBG("The e_client(%p) is a focus client", ec_top);
index 7357698..9a4892d 100644 (file)
@@ -48,11 +48,11 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
    Eina_List *keylist_ptr = NULL, *l = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    switch(mode)
      {
       case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
-         g_mutex_unlock(&krt->grab_key_mutex);
+         g_rec_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_NONE;
 
       case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
@@ -76,10 +76,9 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
          break;
       default:
          KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
-         g_mutex_unlock(&krt->grab_key_mutex);
+         g_rec_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
      }
-   g_mutex_unlock(&krt->grab_key_mutex);
 
    EINA_LIST_FOREACH(keylist_ptr, l, key_node_data)
      {
@@ -91,6 +90,7 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
                {
                   KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_surface %p",
                         key, e_keyrouter_mode_to_string(mode), surface);
+                  g_rec_mutex_unlock(&krt->grab_key_mutex);
                   return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
                }
           }
@@ -100,10 +100,12 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
                {
                   KLDBG("The key(%d) is already grabbed same mode(%s) on the same wl_client %p",
                         key, e_keyrouter_mode_to_string(mode), wc);
+                  g_rec_mutex_unlock(&krt->grab_key_mutex);
                   return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY;
                }
           }
      }
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    return TIZEN_KEYROUTER_ERROR_NONE;
 }
@@ -114,15 +116,16 @@ _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc,
    Eina_List **list = NULL;
    Eina_List *l = NULL, *l_next = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
+   Eina_Bool ret = EINA_FALSE;
 
    EINA_SAFETY_ON_TRUE_RETURN_VAL(((!surface) && (!wc)), EINA_FALSE);
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    list = _e_keyrouter_get_list(mode, key);
    if (!list)
      {
-        g_mutex_unlock(&krt->grab_key_mutex);
-        return EINA_FALSE;
+        ret = EINA_FALSE;
+        goto end;
      }
 
    EINA_LIST_FOREACH_SAFE(*list, l, l_next, key_node_data)
@@ -131,19 +134,20 @@ _e_keyrouter_find_key_in_list(struct wl_resource *surface, struct wl_client *wc,
 
         if ((surface) && (surface == key_node_data->surface))
           {
-             g_mutex_unlock(&krt->grab_key_mutex);
-             return EINA_TRUE;
+             ret = EINA_TRUE;
+             goto end;
           }
         else if ((wc == key_node_data->wc))
           {
-             g_mutex_unlock(&krt->grab_key_mutex);
-             return EINA_TRUE;
+             ret = EINA_TRUE;
+             goto end;
           }
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+end:
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
-   return EINA_FALSE;
+   return ret;
 }
 
 
@@ -169,7 +173,7 @@ e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc
    new_keyptr->focused = focused;
    new_keyptr->status = E_KRT_CSTAT_ALIVE;
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
 
    switch(mode)
      {
@@ -200,10 +204,10 @@ e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc
       default:
          KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
          E_FREE(new_keyptr);
-         g_mutex_unlock(&krt->grab_key_mutex);
+         g_rec_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
      }
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 
    if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
      {
@@ -230,11 +234,11 @@ e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct
    Eina_List *l = NULL, *l_next = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    list = _e_keyrouter_get_list(mode, key);
    if (!list)
      {
-        g_mutex_unlock(&krt->grab_key_mutex);
+        g_rec_mutex_unlock(&krt->grab_key_mutex);
         return;
      }
 
@@ -273,7 +277,7 @@ e_keyrouter_find_and_remove_client_from_list(struct wl_resource *surface, struct
           }
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 }
 
 void
@@ -285,7 +289,7 @@ e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_clien
 
    EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
 
    for (i = 0; i <= krt->max_tizen_hwkeys; i++)
      {
@@ -409,7 +413,7 @@ e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_clien
           }
      }
 
-   g_mutex_unlock(&krt->grab_key_mutex);
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 }
 
 int
index a977711..b7b05f1 100644 (file)
@@ -89,7 +89,7 @@ struct _E_Keyrouter
    E_Input_Event_Handler *_key_down_handler;
    E_Input_Event_Handler *_key_up_handler;
    GMutex event_handler_mutex;
-   GMutex grab_key_mutex;
+   GRecMutex grab_key_mutex;
 };
 
 struct _E_Keyrouter_Grab_Request {
index 60bd722..d28b088 100644 (file)
@@ -147,10 +147,8 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
 
    EINA_SAFETY_ON_NULL_RETURN(wc);
 
-   g_mutex_lock(&krt->grab_key_mutex);
+   g_rec_mutex_lock(&krt->grab_key_mutex);
    press_ptr_list = krt->HardKeys[key].press_ptr;
-   g_mutex_unlock(&krt->grab_key_mutex);
-
    EINA_LIST_FOREACH(press_ptr_list, l, data)
      {
         if (surface)
@@ -175,6 +173,7 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
                }
           }
      }
+   g_rec_mutex_unlock(&krt->grab_key_mutex);
 }
 
 static int