e_devicemgr: fix the memory leak of tizen_input_device objects 53/276453/1
authorduna.oh <duna.oh@samsung.com>
Wed, 15 Jun 2022 08:32:24 +0000 (17:32 +0900)
committerJunseok Kim <juns.kim@samsung.com>
Fri, 17 Jun 2022 04:16:39 +0000 (13:16 +0900)
There is a bug that a client doesn't send 'tizen_input_device_destroy' requests,
then tizen_input_device resources would stay undeleted.
This commit cleans up tizen_input_device resources when a client destroys

The tizen_input_device resource should be removed from the list 'dev->resources'
to prevent accessing invalid resource object.

Change-Id: I54cd0212032b60b8e6278207ef495ab806dc6a86

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..a04aa5d1c78265ad620964421b549c7f3e623ee0 100644 (file)
@@ -88,6 +88,8 @@ _e_devicemgr_wl_device_cb_unbind(struct wl_resource *resource)
    E_Devicemgr_Input_Device *dev;
    E_Devicemgr_Input_Device_User_Data *device_user_data;
 
+   e_devicemgr->wl_data->dev_resources = eina_list_remove(e_devicemgr->wl_data->dev_resources, resource);
+
    if (!(device_user_data = wl_resource_get_user_data(resource))) return;
 
    dev = device_user_data->dev;
@@ -98,7 +100,6 @@ _e_devicemgr_wl_device_cb_unbind(struct wl_resource *resource)
    E_FREE(device_user_data);
 
    if (!dev) return;
-
    dev->resources = eina_list_remove(dev->resources, resource);
 }
 
@@ -156,6 +157,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);
@@ -526,8 +528,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;
 
+   DMINF("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;
+
+        DMINF("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 +601,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 +633,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