e_keyrouter_wl: Modified not to send the event surface to destroyed client 71/319371/1
authorInhong Han <inhong1.han@samsung.com>
Mon, 21 Oct 2024 11:51:37 +0000 (20:51 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 22 Oct 2024 06:04:34 +0000 (15:04 +0900)
Change-Id: I186563a7615d8e485408a7e3a99354243c5ada8e

src/bin/server/e_keyrouter_wl.c

index 1ef09aaedc6240133659f91af8b634be91eda6ab..2a00ae020ea822b090b5fcbe02f81162bc771cb0 100644 (file)
@@ -23,6 +23,8 @@ struct _E_Tizen_Keyrouter
 
    Eina_List *grab_surface_list;
    Eina_List *grab_client_list;
+
+   GRecMutex resource_list_mutex;
 };
 
 EINTERN void
@@ -37,6 +39,7 @@ e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int mode
    wc = wl_resource_get_client(surface);
    EINA_SAFETY_ON_NULL_RETURN(wc);
 
+   g_rec_mutex_lock(&g_tizen_keyrouter->resource_list_mutex);
    EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, res_data)
      {
         if (wl_resource_get_client(res_data) != wc) continue;
@@ -56,6 +59,7 @@ e_keyrouter_wl_event_surface_send(struct wl_resource *surface, int key, int mode
              ELOGF("INPUT", "tizen_keyrouter_send_event_surface|E|", NULL);
           }
      }
+   g_rec_mutex_unlock(&g_tizen_keyrouter->resource_list_mutex);
 }
 
 static void
@@ -199,22 +203,26 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
           {
              if (surface == data->surface)
                {
+                  g_rec_mutex_lock(&g_tizen_keyrouter->resource_list_mutex);
                   EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, resource)
                     {
                        if (wl_resource_get_client(resource) != wc) continue;
 
                        tizen_keyrouter_send_key_cancel(resource, key-8);
                     }
+                  g_rec_mutex_unlock(&g_tizen_keyrouter->resource_list_mutex);
                }
           }
         else if (client == data->wc)
           {
+             g_rec_mutex_lock(&g_tizen_keyrouter->resource_list_mutex);
              EINA_LIST_FOREACH(g_tizen_keyrouter->resources, l, resource)
                {
                   if (wl_resource_get_client(resource) != wc) continue;
 
                   tizen_keyrouter_send_key_cancel(resource, key-8);
                }
+             g_rec_mutex_unlock(&g_tizen_keyrouter->resource_list_mutex);
           }
      }
    g_rec_mutex_unlock(&krt->grab_key_mutex);
@@ -461,7 +469,29 @@ static const struct tizen_keyrouter_interface _e_keyrouter_implementation = {
 static void
 _e_keyrouter_cb_unbind(struct wl_resource *resource)
 {
+   g_rec_mutex_lock(&g_tizen_keyrouter->resource_list_mutex);
    g_tizen_keyrouter->resources = eina_list_remove(g_tizen_keyrouter->resources, resource);
+   g_rec_mutex_unlock(&g_tizen_keyrouter->resource_list_mutex);
+}
+
+static enum wl_iterator_result
+_e_keyrouter_get_resource(struct wl_resource *resource, void *data)
+{
+   g_rec_mutex_lock(&g_tizen_keyrouter->resource_list_mutex);
+   g_tizen_keyrouter->resources = eina_list_remove(g_tizen_keyrouter->resources, resource);
+   g_rec_mutex_unlock(&g_tizen_keyrouter->resource_list_mutex);
+
+   return WL_ITERATOR_CONTINUE;
+}
+
+static void
+_e_keyrouter_cb_wl_client_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_client *client = data;
+
+   wl_client_for_each_resource(client, _e_keyrouter_get_resource, NULL);
+   wl_list_remove(&l->link);
+   E_FREE(l);
 }
 
 /* tizen_keyrouter global object bind function */
@@ -469,6 +499,7 @@ static void
 _e_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 {
    struct wl_resource *resource;
+   struct wl_listener *destroy_listener = NULL;
 
    resource = wl_resource_create(client, &tizen_keyrouter_interface, version, id);
 
@@ -478,12 +509,23 @@ _e_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uin
      {
         KLERR("Failed to create resource ! (version :%d, id:%d)", version, id);
         wl_client_post_no_memory(client);
-        return;
+        return;
      }
 
    g_tizen_keyrouter->resources = eina_list_append(g_tizen_keyrouter->resources, resource);
 
    wl_resource_set_implementation(resource, &_e_keyrouter_implementation, NULL, _e_keyrouter_cb_unbind);
+
+   destroy_listener = E_NEW(struct wl_listener, 1);
+   if (!destroy_listener)
+     {
+        KLERR("Failed to allocate memory for wl_client destroy listener !");
+        wl_resource_destroy(resource);
+        return;
+     }
+
+   destroy_listener->notify = _e_keyrouter_cb_wl_client_destroy;
+   wl_client_add_destroy_listener(client, destroy_listener);
 }
 
 static void
@@ -642,6 +684,8 @@ e_keyrouter_wl_init(struct wl_display *display)
                   &tizen_keyrouter_interface, 2, NULL, _e_keyrouter_cb_bind);
    EINA_SAFETY_ON_NULL_RETURN_VAL(g_tizen_keyrouter->global, NULL);
 
+   g_rec_mutex_init(&g_tizen_keyrouter->resource_list_mutex);
+
    return g_tizen_keyrouter;
 }
 
@@ -683,5 +727,7 @@ e_keyrouter_wl_shutdown(void)
 
    wl_global_destroy(g_tizen_keyrouter->global);
 
+   g_rec_mutex_clear(&g_tizen_keyrouter->resource_list_mutex);
+
    E_FREE(g_tizen_keyrouter);
 }