e_devicemgr: clean up tizen_input_device objects when a client destroys 89/276089/1
authorduna.oh <duna.oh@samsung.com>
Tue, 26 Apr 2022 06:32:56 +0000 (15:32 +0900)
committerJunseok Kim <juns.kim@samsung.com>
Thu, 9 Jun 2022 10:23:26 +0000 (19:23 +0900)
There is a bug that a client does not send destroy requests,
then tizen_input_device objects would stay undeleted.
This commit fixes memory leak of tizen_input_device objs.

Change-Id: I96deae1f41a63dcc7c3525c26a17613d86bce408

src/bin/e_devicemgr_private.h
src/bin/e_devicemgr_wl.c

index afc29b5af386498569aaf07441b6842717612763..4e70fd514436a34432fa42fe57085edbdc91d761 100644 (file)
@@ -136,6 +136,8 @@ struct _E_Devicemgr_Wl_Data
    struct wl_global *global;
    Eina_List *resources;
 
+   Eina_List *dev_resources;
+
 #ifdef HAVE_CYNARA
    cynara *p_cynara;
    Eina_Bool cynara_initialized;
index 4c3f43060fa898c0a8bf026f1d842c04f0944e3b..24b71969f07971157a3a7931d89b491b59ffea5a 100644 (file)
@@ -73,6 +73,8 @@ _e_devicemgr_wl_device_cb_axes_select(struct wl_client *client, struct wl_resour
 static void
 _e_devicemgr_wl_device_cb_release(struct wl_client *client, struct wl_resource *resource)
 {
+   DMDBG("Destroy tizen_input_device: %u (client: %p)", wl_resource_get_id(resource), client);
+
    wl_resource_destroy(resource);
 }
 
@@ -88,18 +90,15 @@ _e_devicemgr_wl_device_cb_unbind(struct wl_resource *resource)
    E_Devicemgr_Input_Device *dev;
    E_Devicemgr_Input_Device_User_Data *device_user_data;
 
+   DMDBG("Unbind tizen_input_device: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
    if (!(device_user_data = wl_resource_get_user_data(resource))) return;
 
-   dev = device_user_data->dev;
-
    device_user_data->dev = NULL;
    device_user_data->dev_mgr_res = NULL;
    device_user_data->seat_res = NULL;
    E_FREE(device_user_data);
 
-   if (!dev) return;
-
-   dev->resources = eina_list_remove(dev->resources, resource);
+   e_devicemgr->wl_data->dev_resources = eina_list_remove(e_devicemgr->wl_data->dev_resources, resource);
 }
 
 void
@@ -156,6 +155,7 @@ e_devicemgr_wl_device_add(E_Devicemgr_Input_Device *dev)
              device_user_data->seat_res = seat_res;
 
              dev->resources = eina_list_append(dev->resources, res);
+             e_devicemgr->wl_data->dev_resources = eina_list_append(e_devicemgr->wl_data->dev_resources, res);
              wl_resource_set_implementation(res, &_e_devicemgr_wl_device_interface, device_user_data,
                                             _e_devicemgr_wl_device_cb_unbind);
              tizen_input_device_manager_send_device_add(dev_mgr_res, serial, dev->identifier, res, seat_res);
@@ -197,19 +197,7 @@ e_devicemgr_wl_device_del(E_Devicemgr_Input_Device *dev)
           }
      }
 
-   EINA_LIST_FREE(dev->resources, res)
-     {
-        device_user_data = wl_resource_get_user_data(res);
-        if (device_user_data)
-          {
-             device_user_data->dev = NULL;
-             device_user_data->dev_mgr_res = NULL;
-             device_user_data->seat_res = NULL;
-             E_FREE(device_user_data);
-          }
-
-        wl_resource_set_user_data(res, NULL);
-     }
+   eina_list_free(dev->resources);
 }
 
 void
@@ -451,6 +439,7 @@ _e_devicemgr_wl_cb_pointer_warp(struct wl_client *client, struct wl_resource *re
 static void
 _e_devicemgr_wl_cb_destroy(struct wl_client *client, struct wl_resource *resource)
 {
+   DMDBG("Destroy tizen_input_device_manager: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
    wl_resource_destroy(resource);
 }
 
@@ -526,8 +515,23 @@ static const struct tizen_input_device_manager_interface _e_devicemgr_wl_impleme
 static void
 _e_devicemgr_wl_cb_unbind(struct wl_resource *resource)
 {
+   struct wl_resource *device_res;
+   Eina_List *l, *l_next;
+   struct wl_client* wc;
+
    if(!e_comp_wl) return;
 
+   DMDBG("Unbind tizen_input_device_manager: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
+
+   EINA_LIST_FOREACH_SAFE(e_devicemgr->wl_data->dev_resources, l, l_next, device_res)
+     {
+        wc = wl_resource_get_client(resource);
+        if (wl_resource_get_client(device_res) != wc) continue;
+
+        DMDBG("Destroy tizen_input_device:%u", wl_resource_get_id(device_res));
+        wl_resource_destroy(device_res);
+     }
+
    e_devicemgr->wl_data->resources = eina_list_remove(e_devicemgr->wl_data->resources, resource);
 }
 
@@ -584,6 +588,7 @@ _e_devicemgr_wl_cb_bind(struct wl_client *client, void *data, uint32_t version,
              device_user_data->seat_res = seat_res;
 
              dev->resources = eina_list_append(dev->resources, device_res);
+             e_devicemgr->wl_data->dev_resources = eina_list_append(e_devicemgr->wl_data->dev_resources, device_res);
 
              wl_resource_set_implementation(device_res, &_e_devicemgr_wl_device_interface, device_user_data,
                                             _e_devicemgr_wl_device_cb_unbind);
@@ -615,6 +620,7 @@ e_devicemgr_wl_init(void)
         return EINA_FALSE;
      }
    e_devicemgr->wl_data->resources = NULL;
+   e_devicemgr->wl_data->dev_resources = NULL;
 
    /* initialization of cynara for checking privilege */
 #ifdef HAVE_CYNARA