e_comp_input: Modified not to send the key event to destroyed client 16/319516/1
authorInhong Han <inhong1.han@samsung.com>
Thu, 24 Oct 2024 06:49:11 +0000 (15:49 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Fri, 25 Oct 2024 00:53:13 +0000 (09:53 +0900)
Change-Id: Ia671683ae831517be0a41b7c31fc505e536685a0

src/bin/inputmgr/e_comp_input.c
src/bin/inputmgr/e_comp_input_intern.h
src/bin/server/e_comp_wl.c
src/bin/server/e_comp_wl_input.c
src/bin/server/e_keyrouter_wl.c
src/include/e_comp_wl_input.h
src/include/e_input.h

index 029a01627de47e4a2764cf1231803afdbf025688..fc790522f79ee0a9b3feb2a8c9e450bbf04cfa8f 100644 (file)
@@ -19,6 +19,8 @@ e_comp_input_init(void)
      }
 
    g_rec_mutex_init(&e_comp_input_key->xkb.keymap_mutex);
+   g_rec_mutex_init(&e_comp_input_key->kbd.resources_mutex);
+   g_rec_mutex_init(&e_comp_input_key->kbd.focused_mutex);
 
    e_comp_input = E_NEW(E_Comp_Input, 1);
    if (!e_comp_input)
@@ -56,6 +58,8 @@ e_comp_input_shutdown(void)
           xkb_context_unref(e_comp_input_key->xkb.context);
 
         g_rec_mutex_clear(&e_comp_input_key->xkb.keymap_mutex);
+        g_rec_mutex_clear(&e_comp_input_key->kbd.resources_mutex);
+        g_rec_mutex_clear(&e_comp_input_key->kbd.focused_mutex);
 
         E_FREE(e_comp_input_key);
      }
@@ -161,3 +165,19 @@ e_input_thread_info_kbd_repeat_rate_get(E_Input_Thread_Info *input_thread_info)
 
    return ((E_Comp_Input_Key_Data *)input_thread_info)->kbd.repeat_rate;
 }
+
+E_API void
+e_input_thread_info_kbd_resource_list_lock(E_Input_Thread_Info *input_thread_info)
+{
+   EINA_SAFETY_ON_NULL_RETURN(input_thread_info);
+
+   g_rec_mutex_lock(&((E_Comp_Input_Key_Data *)input_thread_info)->kbd.resources_mutex);
+}
+
+E_API void
+e_input_thread_info_kbd_resource_list_unlock(E_Input_Thread_Info *input_thread_info)
+{
+   EINA_SAFETY_ON_NULL_RETURN(input_thread_info);
+
+   g_rec_mutex_unlock(&((E_Comp_Input_Key_Data *)input_thread_info)->kbd.resources_mutex);
+}
\ No newline at end of file
index a4d6c242461bb12be477b15c894cd47f58d66ff4..11a2f37aadd6e5f805ae79a0db1473d54ae52592 100644 (file)
@@ -46,6 +46,8 @@ struct _E_Comp_Input_Key_Data
         atomic_int repeat_delay;
         atomic_int repeat_rate;
         unsigned int num_devices;
+        GRecMutex resources_mutex;
+        GRecMutex focused_mutex;
      } kbd;
 };
 
index 210731dd5dc0f3f7270cfcdffbc532a071c5755a..77fb21e4f29cb880dca23751e6ca313448d5741a 100644 (file)
@@ -2187,8 +2187,10 @@ _e_comp_wl_input_thread_send_keys(E_Comp_Wl_Data *comp_wl)
    Eina_List *l;
    double t;
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    if (!e_comp_input_key->kbd.focused)
      {
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
         return;
      }
 
@@ -2204,6 +2206,7 @@ _e_comp_wl_input_thread_send_keys(E_Comp_Wl_Data *comp_wl)
                                   k->key, WL_KEYBOARD_KEY_STATE_PRESSED);
           }
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 }
 
 static Eina_Bool
@@ -2233,19 +2236,26 @@ _e_comp_wl_input_thread_focus_in(void *data)
 
    wc = wl_resource_get_client(surface);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) == wc)
           {
+             g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
              if (!eina_list_data_find(e_comp_input_key->kbd.focused, res))
                e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
+             g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
           }
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    if (!e_comp_input_key->kbd.focused)
      {
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
         return;
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 
    e_comp_input_key->kbd.focus = surface;
    e_comp_wl_input_keyboard_enter_send(surface);
@@ -2313,15 +2323,19 @@ _e_comp_wl_input_thread_focus_out(void *data)
 
    if (!surface) return;
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    if (!eina_list_count(e_comp_input_key->kbd.resources))
      {
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
         return;
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
    /* send keyboard_leave to all keyboard resources */
    serial = wl_display_next_serial(e_comp_wl_display_get());
    t = ecore_time_unix_get();
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
      {
         wl_array_for_each(k, &e_comp_input_key->kbd.keys)
@@ -2334,6 +2348,7 @@ _e_comp_wl_input_thread_focus_out(void *data)
         e_comp_input_key->kbd.focused =
            eina_list_remove_list(e_comp_input_key->kbd.focused, l);
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 }
 
 static void
@@ -3260,6 +3275,7 @@ e_comp_wl_client_surface_finish(E_Client *ec)
    if (surface_client &&
        (ec == e_client_focused_get()))
      {
+        g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
         EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
           {
              if (wl_resource_get_client(res) ==
@@ -3268,6 +3284,7 @@ e_comp_wl_client_surface_finish(E_Client *ec)
                   eina_list_remove_list(e_comp_input_key->kbd.focused, l);
 
           }
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
      }
 
    e_comp_wl_client_surface_set(ec, NULL);
@@ -4286,6 +4303,7 @@ e_comp_wl_key_down(Ecore_Event_Key *ev, E_Device *dev)
         struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
         if (ec && ec->comp_data && surface)
           {
+             g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
              if (e_comp_input_key->kbd.focused)
                {
                   _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_input_key->kbd.focused, ec);
@@ -4296,11 +4314,13 @@ e_comp_wl_key_down(Ecore_Event_Key *ev, E_Device *dev)
                   if (!(k = wl_array_add(&e_comp_input_key->kbd.keys, sizeof(*k))))
                     {
                        DBG("wl_array_add: Out of memory\n");
+                       g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
                        return EINA_FALSE;
                     }
                   k->key = keycode;
                   k->dev = ev->dev;
                }
+             g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
           }
      }
 
@@ -4347,10 +4367,12 @@ e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev)
      {
         ec = e_client_focused_get();
 
+        g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
         if (e_comp_input_key->kbd.focused)
           {
              _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_input_key->kbd.focused, ec);
           }
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
      }
 
    /* update modifier state */
@@ -5022,6 +5044,7 @@ e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, void *dev, uint
         ELOGF("INPUT", "wl_keyboard_send_key:%s:%d|B|", NULL, (state ? "PRESS" : "RELEASE"), keycode);
      }
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
@@ -5053,6 +5076,7 @@ e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, void *dev, uint
         wl_keyboard_send_key(res, serial, time,
                              wl_keycode, state);
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
    if (e_config->key_input_ttrace_enable)
      {
@@ -5111,6 +5135,7 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
    e_input_thread_request_boost();
    e_keyrouter_wl_event_surface_send(surface, wl_keycode, TIZEN_KEYROUTER_MODE_NONE);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
@@ -5126,6 +5151,7 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
         wl_keyboard_send_key(res, serial, time,
                              cancel_keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
    return EINA_TRUE;
 }
index 91aed89092a371b8069336045df130fdccb736eb..2cd2fb963082048a36f029c1b7625f5ea95625c0 100644 (file)
@@ -368,13 +368,17 @@ _e_comp_wl_input_thread_cb_keyboard_unbind(void *data)
 
    resource = *(struct wl_resource **)data;
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    e_comp_input_key->kbd.resources =
      eina_list_remove(e_comp_input_key->kbd.resources, resource);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
      if (res == resource)
        e_comp_input_key->kbd.focused =
          eina_list_remove_list(e_comp_input_key->kbd.focused, l);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 }
 
 static void
@@ -394,7 +398,13 @@ e_comp_wl_input_keyboard_enter_send(struct wl_resource *surface)
    xkb_layout_index_t mod_group;
    E_Comp_Wl_Data *comp_wl;
 
-   if (!e_comp_input_key->kbd.focused) return;
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
+   if (!e_comp_input_key->kbd.focused)
+     {
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+        return;
+     }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 
    e_comp_wl_input_keyboard_modifiers_serialize();
 
@@ -407,6 +417,7 @@ e_comp_wl_input_keyboard_enter_send(struct wl_resource *surface)
 
    mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
      {
         wl_keyboard_send_enter(res, serial, surface,
@@ -418,6 +429,38 @@ e_comp_wl_input_keyboard_enter_send(struct wl_resource *surface)
                                    mod_locked,
                                    mod_group);
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+}
+
+static enum wl_iterator_result
+_e_comp_wl_input_get_resource(struct wl_resource *resource, void *data)
+{
+   Eina_List *l, *ll;
+   struct wl_resource *res;
+
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
+   e_comp_input_key->kbd.resources = eina_list_remove(e_comp_input_key->kbd.resources, resource);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
+   EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
+     {
+        if (res == resource)
+          e_comp_input_key->kbd.focused = eina_list_remove_list(e_comp_input_key->kbd.focused, l);
+     }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
+
+   return WL_ITERATOR_CONTINUE;
+}
+
+static void
+_e_comp_wl_input_cb_wl_client_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_client *client = data;
+
+   wl_client_for_each_resource(client, _e_comp_wl_input_get_resource, NULL);
+   wl_list_remove(&l->link);
+   E_FREE(l);
 }
 
 static void
@@ -433,8 +476,10 @@ _e_comp_wl_input_thread_cb_keyboard_get(void *data)
 
    res = keyboard_get_data->resource;
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    e_comp_input_key->kbd.resources =
      eina_list_append(e_comp_input_key->kbd.resources, res);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 
    /* send current repeat_info */
    if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
@@ -451,7 +496,9 @@ _e_comp_wl_input_thread_cb_keyboard_get(void *data)
    if (!surface) return;
 
    if (keyboard_get_data->client != wl_resource_get_client(surface)) return;
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 
    e_comp_wl_input_keyboard_enter_send(surface);
 }
@@ -460,6 +507,7 @@ static void
 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
 {
    struct wl_resource *res;
+   struct wl_listener *destroy_listener = NULL;
    E_Input_Thread_Request_Keyboard_Get_Data keyboard_get_data;
    E_Comp_Wl_Data *comp_wl = e_comp_wl_get();
 
@@ -489,6 +537,16 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r
    keyboard_get_data.client = client;
 
    _e_comp_wl_input_thread_cb_keyboard_get(&keyboard_get_data);
+
+   destroy_listener = E_NEW(struct wl_listener, 1);
+   if (!destroy_listener)
+     {
+        KLERR("Failed to allocate memory for wl_client destroy listener !");
+        return;
+     }
+
+   destroy_listener->notify = _e_comp_wl_input_cb_wl_client_destroy;
+   wl_client_add_destroy_listener(client, destroy_listener);
 }
 
 static void
@@ -1593,10 +1651,12 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_pat
 
    /* send updated keymap */
    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
                              e_comp_input_key->xkb.fd,
                              e_comp_input_key->xkb.size);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
    TRACE_INPUT_END();
 
    /* update modifiers */
@@ -1871,8 +1931,10 @@ e_comp_wl_input_keyboard_modifiers_update(void)
    E_Comp_Wl_Data *comp_wl = e_comp_wl_get();
 
    if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
+   g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
    if (!e_comp_input_key->kbd.focused)
      {
+       g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
        return;
      }
 
@@ -1883,6 +1945,7 @@ e_comp_wl_input_keyboard_modifiers_update(void)
                                 e_comp_input_key->kbd.mod_latched,
                                 e_comp_input_key->kbd.mod_locked,
                                 e_comp_input_key->kbd.mod_group);
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
 }
 
 EINTERN void
@@ -2244,12 +2307,14 @@ e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
    atomic_store(&e_comp_input_key->kbd.repeat_delay, delay);
    atomic_store(&e_comp_input_key->kbd.repeat_rate, rate);
 
+   g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
           wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate,
                                        e_comp_input_key->kbd.repeat_delay);
      }
+   g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
 }
 
 typedef struct _keycode_map{
@@ -2468,3 +2533,17 @@ e_comp_wl_input_kbd_repeat_rate_get()
    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
    return e_comp_input_key->kbd.repeat_rate;
 }
+
+E_API void
+e_comp_wl_input_kbd_reousrce_list_lock()
+{
+  EINA_SAFETY_ON_NULL_RETURN(e_comp_input_key);
+  g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
+}
+
+E_API void
+e_comp_wl_input_kbd_reousrce_list_unlock()
+{
+  EINA_SAFETY_ON_NULL_RETURN(e_comp_input_key);
+  g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
+}
index 2a00ae020ea822b090b5fcbe02f81162bc771cb0..60e9e10048aee7887784245f563c496b8519600b 100644 (file)
@@ -153,7 +153,9 @@ e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, Eina_Bool pressed, s
 
    if (!focused)
      {
+        g_rec_mutex_lock(&e_comp_input_key->kbd.resources_mutex);
         _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.resources, EINA_FALSE, client, surface);
+        g_rec_mutex_unlock(&e_comp_input_key->kbd.resources_mutex);
         return EINA_FALSE;
      }
 
@@ -167,11 +169,13 @@ e_keyrouter_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, Eina_Bool pressed, s
              struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
              if (surface)
                {
+                  g_rec_mutex_lock(&e_comp_input_key->kbd.focused_mutex);
                   if (e_comp_input_key->kbd.focused)
                     {
                        wc = wl_resource_get_client(surface);
                        _e_keyrouter_wl_key_send(ev, dev, state, e_comp_input_key->kbd.focused, EINA_TRUE, wc, surface);
                     }
+                  g_rec_mutex_unlock(&e_comp_input_key->kbd.focused_mutex);
                }
 
              /* update modifier state */
index 5f0bac2552263d5bf0c93cf554f02574b879fb74..34b3b561be38274fc87e117c6fc28b86f4269de9 100644 (file)
@@ -26,5 +26,7 @@ E_API struct xkb_keymap *e_comp_wl_input_xkb_keymap_get();
 E_API const Eina_List * e_comp_wl_input_kbd_resources_get();
 E_API int               e_comp_wl_input_kbd_repeat_delay_get();
 E_API int               e_comp_wl_input_kbd_repeat_rate_get();
+E_API void              e_comp_wl_input_kbd_reousrce_list_lock();
+E_API void              e_comp_wl_input_kbd_reousrce_list_unlock();
 
 #endif
index 2987c2f7fee76966b6a80717876cb477732fe20b..c00a37ed4a94562f0cb7441ed45746f90c1b3cc3 100644 (file)
@@ -69,6 +69,7 @@ E_API size_t                e_input_thread_info_xkb_size_get(E_Input_Thread_Info
 E_API Eina_List            *e_input_thread_info_kbd_resource_list_get(E_Input_Thread_Info *input_thread_info);
 E_API int                   e_input_thread_info_kbd_repeat_delay_get(E_Input_Thread_Info *input_thread_info);
 E_API int                   e_input_thread_info_kbd_repeat_rate_get(E_Input_Thread_Info *input_thread_info);
-
+E_API void                  e_input_thread_info_kbd_resource_list_lock(E_Input_Thread_Info *input_thread_info);
+E_API void                  e_input_thread_info_kbd_resource_list_unlock(E_Input_Thread_Info *input_thread_info);
 
 #endif