e_devicemgr: clean up device resource when seat/device_manager is destroyed 50/319150/1
authorduna.oh <duna.oh@samsung.com>
Mon, 14 Oct 2024 01:16:43 +0000 (10:16 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 16 Oct 2024 06:58:27 +0000 (15:58 +0900)
Change-Id: I0cc36edb15ab6ce831fc83a99854a7e3a258fd47

src/bin/server/e_devicemgr_wl.c

index bb5a55ab015b2104d4cefb19a89d73530da72e9c..4e361f2fce0b196a150d5838397120526177c5bf 100644 (file)
@@ -9,28 +9,22 @@
 
 #include <tizen-extension-server-protocol.h>
 
-typedef struct _E_Tizen_Devicemgr_Mgr_Data E_Tizen_Devicemgr_Mgr_Data;
 typedef struct _E_Tizen_Devicemgr_User_Data E_Tizen_Devicemgr_User_Data;
 
 struct _E_Tizen_Devicemgr
 {
    struct wl_global *global;
-   Eina_List *mgr_data_list;
-};
-
-struct _E_Tizen_Devicemgr_Mgr_Data
-{
-    struct wl_resource *resource;
-    Eina_List *user_data_list;
+   Eina_List *mgr_resources;
 };
 
 struct _E_Tizen_Devicemgr_User_Data
 {
    E_Devicemgr_Input_Device *dev;
-   struct wl_resource *dev_res;
-   struct wl_resource *dev_mgr_res;
+   struct wl_resource *resource; //resource of tizen_input_device
    struct wl_resource *seat_res;
-   E_Tizen_Devicemgr_Mgr_Data *mgr_data;
+   struct wl_resource *mgr_res;
+   struct wl_listener manager_destroy_listener; //listener for destroy of manager
+   struct wl_listener seat_destroy_listener; //listener for destroy of seat
 };
 
 static E_Tizen_Devicemgr *g_tizen_devicemgr = NULL;
@@ -73,20 +67,82 @@ _e_devicemgr_wl_device_data_destroy(E_Tizen_Devicemgr_User_Data *device_user_dat
 {
    if (!device_user_data) return;
 
-   DMDBG("Destroy device user data. (res: %u)", device_user_data->dev_res ? wl_resource_get_id(device_user_data->dev_res) : 0x0);
-
-   if (device_user_data->mgr_data)
-     device_user_data->mgr_data->user_data_list = eina_list_remove(device_user_data->mgr_data->user_data_list, device_user_data);
+   DMDBG("Destroy device user data. (res: %u)", device_user_data->resource ? wl_resource_get_id(device_user_data->resource) : 0x0);
 
    if (device_user_data->dev)
-     device_user_data->dev->resources = eina_list_remove(device_user_data->dev->resources, device_user_data->dev_res);
+     device_user_data->dev->resources = eina_list_remove(device_user_data->dev->resources, device_user_data->resource);
 
-   if (device_user_data->dev_res)
-     wl_resource_set_user_data(device_user_data->dev_res, NULL);
+   if (device_user_data->resource)
+     wl_resource_set_user_data(device_user_data->resource, NULL);
+
+   if (device_user_data->manager_destroy_listener.notify)
+     {
+        wl_list_remove(&device_user_data->manager_destroy_listener.link);
+        device_user_data->manager_destroy_listener.notify = NULL;
+     }
+   if (device_user_data->seat_destroy_listener.notify)
+     {
+        wl_list_remove(&device_user_data->seat_destroy_listener.link);
+        device_user_data->seat_destroy_listener.notify = NULL;
+     }
 
    E_FREE(device_user_data);
 }
 
+static void
+_e_devicemgr_wl_device_cb_seat_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_resource *seat_resource = (struct wl_resource *)data;
+   E_Tizen_Devicemgr_User_Data *device_user_data;
+
+   DMDBG("Listener(%p) called: seat_resource: %p destroyed", l, seat_resource);
+
+   device_user_data = container_of(l, E_Tizen_Devicemgr_User_Data,
+                      seat_destroy_listener);
+   if (!device_user_data) return;
+
+   if (device_user_data->seat_destroy_listener.notify)
+     {
+        wl_list_remove(&device_user_data->seat_destroy_listener.link);
+        device_user_data->seat_destroy_listener.notify = NULL;
+     }
+   if (device_user_data->resource)
+     {
+        DMDBG("Destroy device resource. (res: %u)", wl_resource_get_id(device_user_data->resource));
+        wl_resource_destroy(device_user_data->resource);
+        device_user_data->resource = NULL;
+     }
+
+   device_user_data->seat_res = NULL;
+}
+
+static void
+_e_devicemgr_wl_device_cb_manager_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_resource *mgr_resource = (struct wl_resource *)data;
+   E_Tizen_Devicemgr_User_Data *device_user_data;
+
+   DMDBG("Listener(%p) called: mgr_resource: %p destroyed", l, mgr_resource);
+
+   device_user_data = container_of(l, E_Tizen_Devicemgr_User_Data,
+                      manager_destroy_listener);
+   if (!device_user_data) return;
+
+   if (device_user_data->manager_destroy_listener.notify)
+     {
+        wl_list_remove(&device_user_data->manager_destroy_listener.link);
+        device_user_data->manager_destroy_listener.notify = NULL;
+     }
+   if (device_user_data->resource)
+     {
+        DMDBG("Destroy device resource. (res: %u)", wl_resource_get_id(device_user_data->resource));
+        wl_resource_destroy(device_user_data->resource);
+        device_user_data->resource = NULL;
+     }
+
+   device_user_data->mgr_res = NULL;
+}
+
 static void
 _e_devicemgr_wl_device_cb_unbind(struct wl_resource *resource)
 {
@@ -122,7 +178,6 @@ e_devicemgr_wl_device_add(E_Devicemgr_Input_Device *dev)
    struct wl_client *wc;
    E_Tizen_Devicemgr_User_Data *device_user_data;
    struct wl_array axes;
-   E_Tizen_Devicemgr_Mgr_Data *mgr_data;
    E_Comp_Wl_Data *comp_wl;
 
    /* TODO: find the seat corresponding to event */
@@ -134,10 +189,8 @@ e_devicemgr_wl_device_add(E_Devicemgr_Input_Device *dev)
      {
         wc = wl_resource_get_client(seat_res);
 
-        EINA_LIST_FOREACH(g_tizen_devicemgr->mgr_data_list, ll, mgr_data)
+        EINA_LIST_FOREACH(g_tizen_devicemgr->mgr_resources, ll, dev_mgr_res)
           {
-             dev_mgr_res = mgr_data->resource;
-             if (!dev_mgr_res) continue;
              if (wl_resource_get_client(dev_mgr_res) != wc) continue;
 
              res = wl_resource_create(wc, &tizen_input_device_interface, 1, 0);
@@ -156,17 +209,25 @@ e_devicemgr_wl_device_add(E_Devicemgr_Input_Device *dev)
                   wl_resource_destroy(res);
                   break;
                }
+
+             wl_resource_set_implementation(res, &_e_devicemgr_wl_device_interface, device_user_data,
+                                            _e_devicemgr_wl_device_cb_unbind);
+
              device_user_data->dev = dev;
-             device_user_data->dev_mgr_res = dev_mgr_res;
+             device_user_data->resource = res;
+
              device_user_data->seat_res = seat_res;
-             device_user_data->dev_res = res;
-             device_user_data->mgr_data = mgr_data;
+             device_user_data->seat_destroy_listener.notify =
+               _e_devicemgr_wl_device_cb_seat_destroy;
+             wl_resource_add_destroy_listener(seat_res, &device_user_data->seat_destroy_listener);
+
+             device_user_data->mgr_res = dev_mgr_res;
+             device_user_data->manager_destroy_listener.notify =
+               _e_devicemgr_wl_device_cb_manager_destroy;
+             wl_resource_add_destroy_listener(dev_mgr_res, &device_user_data->manager_destroy_listener);
 
              dev->resources = eina_list_append(dev->resources, res);
-             mgr_data->user_data_list = eina_list_append(mgr_data->user_data_list, device_user_data);
 
-             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);
              tizen_input_device_send_device_info(res, dev->name, dev->clas, dev->subclas, &axes);
           }
@@ -186,15 +247,14 @@ e_devicemgr_wl_device_del(E_Devicemgr_Input_Device *dev)
      {
         device_user_data = wl_resource_get_user_data(res);
         if (!device_user_data) continue;
-        if (!device_user_data->dev_mgr_res || !device_user_data->seat_res ||
-            !device_user_data->dev_res)
+        if (!device_user_data->mgr_res || !device_user_data->seat_res || !device_user_data->resource)
           continue;
 
         device_user_data->dev = NULL;
         tizen_input_device_manager_send_device_remove(
-                                   device_user_data->dev_mgr_res,
+                                   device_user_data->mgr_res,
                                    serial, dev->identifier,
-                                   device_user_data->dev_res,
+                                   device_user_data->resource,
                                    device_user_data->seat_res);
 
         _e_devicemgr_wl_device_data_destroy(device_user_data); // Make inert
@@ -257,7 +317,6 @@ e_devicemgr_wl_touch_max_count_send(int slot, struct wl_resource *res, struct wl
    Eina_List *l, *ll;
    uint32_t serial;
    struct wl_client *wc;
-   E_Tizen_Devicemgr_Mgr_Data *mgr_data;
    E_Comp_Wl_Data *comp_wl;
 
    comp_wl = e_comp_wl_get();
@@ -275,9 +334,8 @@ e_devicemgr_wl_touch_max_count_send(int slot, struct wl_resource *res, struct wl
           {
              wc = wl_resource_get_client(seat_resource);
 
-             EINA_LIST_FOREACH(g_tizen_devicemgr->mgr_data_list, ll, mgr_data)
+             EINA_LIST_FOREACH(g_tizen_devicemgr->mgr_resources, ll, dev_mgr_resource)
                {
-                  dev_mgr_resource = mgr_data->resource;
                   if (!dev_mgr_resource) continue;
                   if (wl_resource_get_client(dev_mgr_resource) != wc) continue;
                   if (wl_resource_get_version(dev_mgr_resource) < 4) continue;
@@ -647,24 +705,11 @@ static const struct tizen_input_device_manager_interface _e_devicemgr_wl_impleme
 static void
 _e_devicemgr_wl_cb_unbind(struct wl_resource *resource)
 {
-   E_Tizen_Devicemgr_Mgr_Data *mgr_data;
-   E_Tizen_Devicemgr_User_Data *device_user_data;
-
    if(!e_comp_wl_get()) return;
 
-   mgr_data = wl_resource_get_user_data(resource);
-   if (!mgr_data) return;
-
-   DMDBG("Unbind tizen_input_device_manager: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
-
-   EINA_LIST_FREE(mgr_data->user_data_list, device_user_data)
-     {
-        device_user_data->mgr_data = NULL;
-        _e_devicemgr_wl_device_data_destroy(device_user_data);
-     }
-   g_tizen_devicemgr->mgr_data_list = eina_list_remove(g_tizen_devicemgr->mgr_data_list, mgr_data);
+   DMINF("Unbind tizen_input_device_manager: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
 
-   E_FREE(mgr_data);
+   g_tizen_devicemgr->mgr_resources = eina_list_remove(g_tizen_devicemgr->mgr_resources, resource);
 }
 
 static void
@@ -676,34 +721,22 @@ _e_devicemgr_wl_cb_bind(struct wl_client *client, void *data, uint32_t version,
    E_Devicemgr_Input_Device *dev;
    struct wl_array axes;
    E_Tizen_Devicemgr_User_Data *device_user_data;
-   E_Tizen_Devicemgr_Mgr_Data *mgr_data;
    E_Comp_Wl_Data *comp_wl;
 
-   mgr_data = E_NEW(E_Tizen_Devicemgr_Mgr_Data, 1);
-   if (!mgr_data)
-     {
-        DMERR("Failed to allocate memory for input device mgr data\n");
-        wl_client_post_no_memory(client);
-        return;
-     }
-
    if (!(res = wl_resource_create(client, &tizen_input_device_manager_interface, version, id)))
      {
         DMERR("Could not create tizen_input_device_manager_interface resource: %m");
         wl_client_post_no_memory(client);
-        E_FREE(mgr_data);
         return;
      }
 
    DMINF("Bind tizen_input_device_manager: %u (client: %p)", wl_resource_get_id(res), wl_resource_get_client(res));
 
-   mgr_data->resource = res;
-   mgr_data->user_data_list = NULL;
-   g_tizen_devicemgr->mgr_data_list = eina_list_append(g_tizen_devicemgr->mgr_data_list, mgr_data);
-
-   wl_resource_set_implementation(res, &_e_devicemgr_wl_implementation, mgr_data,
+   wl_resource_set_implementation(res, &_e_devicemgr_wl_implementation, NULL,
                                   _e_devicemgr_wl_cb_unbind);
 
+   g_tizen_devicemgr->mgr_resources = eina_list_append(g_tizen_devicemgr->mgr_resources, res);
+
    comp_wl = e_comp_wl_get();
    EINA_LIST_FOREACH(comp_wl->seat.resources, l, seat_res)
      {
@@ -728,6 +761,7 @@ _e_devicemgr_wl_cb_bind(struct wl_client *client, void *data, uint32_t version,
                   g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
                   return;
                }
+
              device_user_data = E_NEW(E_Tizen_Devicemgr_User_Data, 1);
              if (!device_user_data)
                {
@@ -737,17 +771,24 @@ _e_devicemgr_wl_cb_bind(struct wl_client *client, void *data, uint32_t version,
                   g_rec_mutex_unlock(&e_devicemgr->device_list_mutex);
                   return;
                }
+
+             wl_resource_set_implementation(device_res, &_e_devicemgr_wl_device_interface, device_user_data,
+                                            _e_devicemgr_wl_device_cb_unbind);
+
              device_user_data->dev = dev;
-             device_user_data->dev_mgr_res = res;
+             device_user_data->resource = device_res;
+
              device_user_data->seat_res = seat_res;
-             device_user_data->dev_res = device_res;
-             device_user_data->mgr_data = mgr_data;
+             device_user_data->seat_destroy_listener.notify =
+               _e_devicemgr_wl_device_cb_seat_destroy;
+             wl_resource_add_destroy_listener(seat_res, &device_user_data->seat_destroy_listener);
 
-             dev->resources = eina_list_append(dev->resources, device_res);
-             mgr_data->user_data_list = eina_list_append(mgr_data->user_data_list, device_user_data);
+             device_user_data->mgr_res = res;
+             device_user_data->manager_destroy_listener.notify =
+               _e_devicemgr_wl_device_cb_manager_destroy;
+             wl_resource_add_destroy_listener(res, &device_user_data->manager_destroy_listener);
 
-             wl_resource_set_implementation(device_res, &_e_devicemgr_wl_device_interface, device_user_data,
-                                            _e_devicemgr_wl_device_cb_unbind);
+             dev->resources = eina_list_append(dev->resources, device_res);
 
              tizen_input_device_manager_send_device_add(res, serial, dev->identifier, device_res, seat_res);
              tizen_input_device_send_device_info(device_res, dev->name, dev->clas, dev->subclas, &axes);
@@ -775,7 +816,7 @@ e_devicemgr_wl_init(struct wl_display *display)
         DMERR("Could not add tizen_input_device_manager to wayland globals");
         return NULL;
      }
-   g_tizen_devicemgr->mgr_data_list = NULL;
+   g_tizen_devicemgr->mgr_resources = NULL;
 
    return g_tizen_devicemgr;
 }
@@ -785,7 +826,7 @@ e_devicemgr_wl_shutdown(void)
 {
    if (!g_tizen_devicemgr) return;
 
-   eina_list_free(g_tizen_devicemgr->mgr_data_list);
+   eina_list_free(g_tizen_devicemgr->mgr_resources);
 
    /* destroy the global seat resource */
    wl_global_destroy(g_tizen_devicemgr->global);