e_keyrouter_wl: Modified not to send the event surface to destroyed client 59/319359/5 accepted/tizen/8.0/unified/20241023.163006
authorInhong Han <inhong1.han@samsung.com>
Tue, 22 Oct 2024 01:27:49 +0000 (10:27 +0900)
committerInhong Han <inhong1.han@samsung.com>
Tue, 22 Oct 2024 05:02:23 +0000 (14:02 +0900)
Change-Id: I12f51e8f29edec2f74d7249d961f861315e3350b

src/bin/e_keyrouter_private.h
src/bin/e_keyrouter_wl.c

index da0e497db51ae84d9c45583e6ffc54197e2c312f..020146721d6dbaa01574111731259b0aba4d1ceb 100644 (file)
@@ -90,6 +90,7 @@ struct _E_Keyrouter
    E_Input_Event_Handler *_key_down_handler;
    E_Input_Event_Handler *_key_up_handler;
    GRecMutex grab_key_mutex;
+   GRecMutex resource_list_mutex;
 };
 
 struct _E_Keyrouter_Grab_Request {
index 6f67135eef75b647546fea2300d7146740ebd389..66540adb86ec088077fc65921ff4cbb46c4caaac 100644 (file)
@@ -13,6 +13,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(&krt->resource_list_mutex);
    EINA_LIST_FOREACH(krt->resources, l, res_data)
      {
         if (wl_resource_get_client(res_data) != wc) continue;
@@ -32,6 +33,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(&krt->resource_list_mutex);
 }
 
 static void
@@ -183,22 +185,26 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
           {
              if (surface == data->surface)
                {
+                  g_rec_mutex_lock(&krt->resource_list_mutex);
                   EINA_LIST_FOREACH(krt->resources, l, resource)
                     {
                        if (wl_resource_get_client(resource) != wc) continue;
 
                        tizen_keyrouter_send_key_cancel(resource, key-8);
                     }
+                  g_rec_mutex_unlock(&krt->resource_list_mutex);
                }
           }
         else if (client == data->wc)
           {
+             g_rec_mutex_lock(&krt->resource_list_mutex);
              EINA_LIST_FOREACH(krt->resources, l, resource)
                {
                   if (wl_resource_get_client(resource) != wc) continue;
 
                   tizen_keyrouter_send_key_cancel(resource, key-8);
                }
+             g_rec_mutex_unlock(&krt->resource_list_mutex);
           }
      }
    g_rec_mutex_unlock(&krt->grab_key_mutex);
@@ -416,7 +422,29 @@ static const struct tizen_keyrouter_interface _e_keyrouter_implementation = {
 static void
 _e_keyrouter_cb_unbind(struct wl_resource *resource)
 {
+   g_rec_mutex_lock(&krt->resource_list_mutex);
    krt->resources = eina_list_remove(krt->resources, resource);
+   g_rec_mutex_unlock(&krt->resource_list_mutex);
+}
+
+static enum wl_iterator_result
+_e_keyrouter_get_resource(struct wl_resource *resource, void *data)
+{
+   g_rec_mutex_lock(&krt->resource_list_mutex);
+   krt->resources = eina_list_remove(krt->resources, resource);
+   g_rec_mutex_unlock(&krt->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 */
@@ -425,6 +453,7 @@ _e_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uin
 {
    E_KeyrouterPtr krt_instance = data;
    struct wl_resource *resource;
+   struct wl_listener *destroy_listener = NULL;
 
    resource = wl_resource_create(client, &tizen_keyrouter_interface, version, id);
 
@@ -434,12 +463,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;
      }
 
    krt->resources = eina_list_append(krt->resources, resource);
 
    wl_resource_set_implementation(resource, &_e_keyrouter_implementation, krt_instance, _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
@@ -646,6 +686,8 @@ e_keyrouter_wl_init(void)
      }
 #endif
 
+   g_rec_mutex_init(&krt->resource_list_mutex);
+
    return EINA_TRUE;
 }
 
@@ -688,4 +730,6 @@ e_keyrouter_wl_shutdown(void)
 #ifdef HAVE_CYNARA
    if (krt->p_cynara) cynara_finish(krt->p_cynara);
 #endif
+
+   g_rec_mutex_clear(&krt->resource_list_mutex);
 }