e_input_backend: process device add or remove asynchronously 49/320749/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Wed, 11 Sep 2024 11:10:59 +0000 (20:10 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Fri, 22 Nov 2024 01:10:46 +0000 (10:10 +0900)
Change-Id: I662f0ca0b7da2fee51b9fda1b2ffa9a8ef97bb85
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/inputmgr/e_input_backend.c
src/bin/inputmgr/e_input_evdev.c

index 34ad65f90d0603b5af318665d83bc5363f736b2d..dee510c9bfa9bb762d121ffec19d0be1bba42e4a 100644 (file)
@@ -28,6 +28,13 @@ typedef struct {
     unsigned int data_length;
 } E_Input_Thread_Request_Data;
 
+typedef struct
+{
+   E_Input_Evdev *evdev;
+   Ecore_Device_Class clas;
+   Ecore_Device_Subclass subclas;
+} E_Device_Info;
+
 #define TS_DO
 #ifdef TS_DO
 static double t0, t1, t2;
@@ -133,12 +140,10 @@ _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool
    E_Input *e_input;
    const char *name, *identifier;
 
-   ecore_thread_main_loop_begin();
-
-   if (!(name = ecore_device_name_get(dev))) goto end;
-   if (!(identifier = ecore_device_identifier_get(dev))) goto end;
+   if (!(name = ecore_device_name_get(dev))) return;
+   if (!(identifier = ecore_device_identifier_get(dev))) return;
 
-   if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) goto end;
+   if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
 
    e_input = e_input_get();
 
@@ -152,13 +157,12 @@ _e_input_ecore_device_event(Ecore_Device *dev, const char* seat_name, Eina_Bool
    e->clas = ecore_device_class_get(dev);
    e->subclas = ecore_device_subclass_get(dev);
 
+   INF("[%s Device] device name(%s), identifier(%s), class(%s), subclass(%d)", flag ? "Add" : "Remove", e->name, e->identifier, _e_input_ecore_device_class_to_string(e->clas), e->subclas);
+
    if (flag)
      ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _e_input_ecore_device_info_free, NULL);
    else
      ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _e_input_ecore_device_info_free, NULL);
-
-end:
-   ecore_thread_main_loop_end();
 }
 
 static E_Input_Seat *
@@ -176,7 +180,7 @@ _seat_create(E_Input_Backend *input, const char *seat)
      {
         ERR("Failed to create an ecore device for a seat !\n");
         ecore_thread_main_loop_end();
-               return NULL;
+        return NULL;
      }
 
    ecore_device_name_set(ecore_dev, seat);
@@ -190,7 +194,7 @@ _seat_create(E_Input_Backend *input, const char *seat)
      {
         ERR("Failed to create an ecore device for a seat !\n");
         ecore_thread_main_loop_end();
-               return NULL;
+        return NULL;
      }
 
    e_device_name_set(e_dev, seat);
@@ -216,9 +220,9 @@ _seat_create(E_Input_Backend *input, const char *seat)
    s->dev = input->dev;
 
    ecore_event_add(E_INPUT_EVENT_SEAT_ADD, NULL, NULL, NULL);
-   ecore_thread_main_loop_end();
 
    _e_input_ecore_device_event(ecore_dev, seat, EINA_TRUE);
+   ecore_thread_main_loop_end();
 
    return s;
 }
@@ -237,17 +241,25 @@ _seat_get(E_Input_Backend *input, const char *seat)
    return _seat_create(input, seat);
 }
 
-static Eina_Bool
-_e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_Device_Subclass subclas)
+static void
+_e_input_add_ecore_device_async_cb(void *data)
 {
+   E_Device_Info *dev_info = data;
+   E_Input_Evdev *evdev = NULL;
+   Ecore_Device_Class clas;
+   Ecore_Device_Subclass subclas;
+
+   if (!dev_info) return;
+
+   evdev = dev_info->evdev;
+   clas = dev_info->clas;
+   subclas = dev_info->subclas;
+
    const Eina_List *dev_list = NULL;
    const Eina_List *l;
    Ecore_Device *dev = NULL;
-   E_Device *e_dev = NULL;
    const char *identifier;
 
-   if (!evdev || !evdev->path) return EINA_FALSE;
-
    dev_list = ecore_device_list();
    if (dev_list)
      {
@@ -259,7 +271,7 @@ _e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_D
              if ((ecore_device_class_get(dev) == clas) && (!strcmp(identifier, evdev->path)))
                {
                   ERR("Found same device in device list");
-                  return EINA_FALSE;
+                  return;
                }
           }
      }
@@ -270,7 +282,7 @@ _e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_D
      {
         ERR("Failed to create ecore device");
         evdev->ecore_dev = NULL;
-        return EINA_FALSE;
+        return;
      }
 
    ecore_device_name_set(dev, evdev->name);
@@ -300,6 +312,35 @@ _e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_D
         evdev->ecore_dev_list = eina_list_append(evdev->ecore_dev_list, ecore_device_ref(dev));
      }
 
+   _e_input_ecore_device_event(dev, evdev->seat ? evdev->seat->name : NULL, EINA_TRUE);
+
+   E_FREE(dev_info);
+}
+
+static void
+_e_input_device_event_add(const char *name, const char *identifier, const char *seatname, Ecore_Device_Class clas, Ecore_Device_Subclass subclas, Eina_Bool flag)
+{
+   Ecore_Event_Device_Info *ecore_dev_info = NULL;
+   E_Input_Event_Source *input_event_source = e_input_event_source_get();
+
+   if (!(ecore_dev_info = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
+
+   ecore_dev_info->name = eina_stringshare_add(name);
+   ecore_dev_info->identifier = eina_stringshare_add(identifier);
+   ecore_dev_info->seatname = eina_stringshare_add(seatname);
+   ecore_dev_info->clas = clas;
+   ecore_dev_info->subclas = subclas;
+
+   e_input_event_add(input_event_source, flag ? ECORE_EVENT_DEVICE_ADD : ECORE_EVENT_DEVICE_DEL, ecore_dev_info, _e_input_ecore_device_info_free, NULL);
+}
+
+static Eina_Bool
+_e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_Device_Subclass subclas)
+{
+   E_Device *e_dev = NULL;
+   E_Device_Info *dev_info = NULL;
+   if (!evdev || !evdev->path) return EINA_FALSE;
+
    const GList *device_list = e_device_list_get();
    const gchar *device_identifier;
    for (GList *list = g_list_first((GList *)device_list); list; list = list->next)
@@ -364,29 +405,38 @@ _e_input_add_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas, Ecore_D
         evdev->e_dev_list = g_list_append(evdev->e_dev_list, g_object_ref(e_dev));
      }
 
-   _e_input_ecore_device_event(dev, evdev->seat ? evdev->seat->name : NULL, EINA_TRUE);
-
    INF("[Add Device] device name(%s), identifier(%s), class(%s), subclass(%d)", e_device_name_get(e_dev), evdev->path, _e_input_ecore_device_class_to_string(clas), subclas);
 
+   _e_input_device_event_add(evdev->name, evdev->path, evdev->seat ? evdev->seat->name : NULL, clas, subclas, EINA_TRUE);
+
+   dev_info = E_NEW(E_Device_Info, 1);
+   dev_info->evdev = evdev;
+   dev_info->clas = clas;
+   dev_info->subclas = subclas;
+
+   ecore_main_loop_thread_safe_call_async(_e_input_add_ecore_device_async_cb, dev_info);
+
    return EINA_TRUE;
 }
 
-static Eina_Bool
-_e_input_remove_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas)
+static void
+_e_input_remove_ecore_device_async_cb(void *cb_data)
 {
-   Eina_Bool ret = EINA_FALSE;
+   E_Device_Info *dev_info = cb_data;
    const Eina_List *dev_list = NULL, *l;
-   const GList *e_dev_list = NULL;
    Eina_List *ll, *ll_next;
-   Ecore_Device *dev = NULL, *data;
+   Ecore_Device *dev, *data;
    const char *identifier;
-   const gchar *device_identifier;
-   const char *device_remove_log = NULL;
+   E_Input_Evdev *evdev;
+   Ecore_Device_Class clas;
 
-   if (!evdev->path) return EINA_FALSE;
+   if (!dev_info) return;
+
+   evdev = dev_info->evdev;
+   clas = dev_info->clas;
 
    dev_list = ecore_device_list();
-   if (!dev_list) return EINA_FALSE;
+   if (!dev_list) return;
 
    EINA_LIST_FOREACH(dev_list, l, dev)
       {
@@ -413,10 +463,21 @@ _e_input_remove_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas)
                 }
               _e_input_ecore_device_event(dev, evdev->seat ? evdev->seat->name : NULL, EINA_FALSE);
               ecore_device_del(dev);
-              ret = EINA_TRUE;
            }
       }
 
+   E_FREE(dev_info);
+}
+
+static Eina_Bool
+_e_input_remove_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas)
+{
+   Eina_Bool ret = EINA_FALSE;
+   const GList *e_dev_list = NULL;
+   const gchar *device_identifier;
+   const char *device_remove_log = NULL;
+   E_Device_Info *dev_info = NULL;
+
    e_dev_list = e_device_list_get();
    if (!e_dev_list)
      {
@@ -446,6 +507,8 @@ _e_input_remove_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas)
                                                          _e_input_ecore_device_class_to_string(clas),
                                                          e_device_subclass_get(device));
 
+             _e_input_device_event_add(e_device_name_get(device), device_identifier, evdev->seat ? evdev->seat->name : NULL, clas, e_device_subclass_get(device), EINA_FALSE);
+
              if (evdev->e_dev)
                {
                   g_object_unref(device);
@@ -469,6 +532,12 @@ _e_input_remove_ecore_device(E_Input_Evdev *evdev, Ecore_Device_Class clas)
         eina_stringshare_del(device_remove_log);
      }
 
+   dev_info = E_NEW(E_Device_Info, 1);
+   dev_info->evdev = evdev;
+   dev_info->clas = clas;
+
+   ecore_main_loop_thread_safe_call_async(_e_input_remove_ecore_device_async_cb, dev_info);
+
    return ret;
 }
 
@@ -530,11 +599,34 @@ _e_input_device_add(E_Input_Evdev *evdev)
    return ret;
 }
 
+static void
+_ecore_device_remove_async_cb(void *cb_data)
+{
+   E_Input_Evdev *evdev = cb_data;
+   Ecore_Device *data;
+
+   if (evdev->ecore_dev_list)
+     {
+        if (eina_list_count(evdev->ecore_dev_list) > 0)
+          {
+             EINA_LIST_FREE(evdev->ecore_dev_list, data)
+               {
+                  WRN("Invalid device is left. name: %s, identifier: %s, clas: %s\n",
+                      ecore_device_name_get(data), ecore_device_identifier_get(data),
+                      _e_input_ecore_device_class_to_string(ecore_device_class_get(data)));
+
+                  ecore_device_unref(data);
+                  ecore_device_del(data);
+               }
+          }
+        evdev->ecore_dev_list = NULL;
+     }
+}
+
 void
 _e_input_device_remove(E_Input_Evdev *evdev)
 {
    Ecore_Device_Class clas = ECORE_DEVICE_CLASS_NONE;
-   Ecore_Device *data;
 
    if (evdev->caps & E_INPUT_SEAT_POINTER)
      {
@@ -553,22 +645,7 @@ _e_input_device_remove(E_Input_Evdev *evdev)
         _e_input_remove_ecore_device(evdev, clas);
      }
 
-   if (evdev->ecore_dev_list)
-     {
-        if (eina_list_count(evdev->ecore_dev_list) > 0)
-          {
-             EINA_LIST_FREE(evdev->ecore_dev_list, data)
-               {
-                  WRN("Invalid device is left. name: %s, identifier: %s, clas: %s\n",
-                      ecore_device_name_get(data), ecore_device_identifier_get(data),
-                      _e_input_ecore_device_class_to_string(ecore_device_class_get(data)));
-
-                  ecore_device_unref(data);
-                  ecore_device_del(data);
-               }
-          }
-        evdev->ecore_dev_list = NULL;
-     }
+   ecore_main_loop_thread_safe_call_async(_ecore_device_remove_async_cb, evdev);
 }
 
 static void
@@ -582,20 +659,18 @@ _device_added(E_Input_Backend *input, struct libinput_device *device)
    libinput_seat = libinput_device_get_seat(device);
    seat_name = libinput_seat_get_logical_name(libinput_seat);
 
-   ecore_thread_main_loop_begin();
-
    /* try to get a seat */
    if (!(seat = _seat_get(input, seat_name)))
      {
         ERR("Could not get matching seat: %s", seat_name);
-        goto end;
+        return;
      }
 
    /* try to create a new evdev device */
    if (!(evdev = e_input_evdev_device_create(seat, device)))
      {
         ERR("Failed to create new evdev device");
-        goto end;
+        return;
      }
 
    /* append this device to the seat */
@@ -604,11 +679,7 @@ _device_added(E_Input_Backend *input, struct libinput_device *device)
    if (EINA_FALSE == _e_input_device_add(evdev))
      {
         ERR("Failed to create evas device !\n");
-        goto end;
      }
-
-end:
-   ecore_thread_main_loop_end();
 }
 
 static void
@@ -624,8 +695,6 @@ _device_removed(E_Input_Backend *input, struct libinput_device *device)
         return;
      }
 
-   ecore_thread_main_loop_begin();
-
    _e_input_device_remove(evdev);
 
    /* remove this evdev from the seat's list of devices */
@@ -633,8 +702,6 @@ _device_removed(E_Input_Backend *input, struct libinput_device *device)
 
    /* destroy this evdev */
    e_input_evdev_device_destroy(evdev);
-
-   ecore_thread_main_loop_end();
 }
 
 static int
index c781e94ea938df1618fce1785b08bffbb37672e9..8197ffc2ab3c2b0571ca98039a99394f2600522c 100644 (file)
@@ -2500,23 +2500,13 @@ e_input_evdev_device_create(E_Input_Seat *seat, struct libinput_device *device)
    return evdev;
 }
 
-void
-e_input_evdev_device_destroy(E_Input_Evdev *evdev)
+static void
+_evdev_device_destroy_async_cb(void *data)
 {
+   E_Input_Evdev *evdev = data;
    Ecore_Device *dev;
    E_Input_Pending_Event *ev;
 
-   EINA_SAFETY_ON_NULL_RETURN(evdev);
-
-   if (evdev->caps & E_INPUT_SEAT_KEYBOARD)
-     {
-        if (evdev->xkb.state) xkb_state_unref(evdev->xkb.state);
-
-        if (evdev->xkb.keymap) xkb_map_unref(evdev->xkb.keymap);
-     }
-
-   ecore_thread_main_loop_begin();
-
    if (evdev->ecore_dev) ecore_device_del(evdev->ecore_dev);
    if (evdev->ecore_dev_list)
      EINA_LIST_FREE(evdev->ecore_dev_list, dev)
@@ -2524,22 +2514,8 @@ e_input_evdev_device_destroy(E_Input_Evdev *evdev)
           ecore_device_del(dev);
        }
 
-   if (evdev->e_dev) g_object_unref(evdev->e_dev);
-   if (evdev->e_dev_list)
-     {
-        GList *glist = evdev->e_dev_list;
-        E_Device *e_dev;
-        while (glist)
-          {
-             e_dev = glist->data;
-             g_object_unref(e_dev);
-
-             glist = g_list_next(glist);
-          }
-     }
    if (evdev->name) eina_stringshare_del(evdev->name);
    if (evdev->path) eina_stringshare_del(evdev->path);
-   if (evdev->device) libinput_device_unref(evdev->device);
    if (evdev->key_remap_hash) eina_hash_free(evdev->key_remap_hash);
    if (evdev->touch.coords)
      {
@@ -2557,11 +2533,40 @@ e_input_evdev_device_destroy(E_Input_Evdev *evdev)
           }
      }
 
-   ecore_thread_main_loop_end();
-
    free(evdev);
 }
 
+void
+e_input_evdev_device_destroy(E_Input_Evdev *evdev)
+{
+   EINA_SAFETY_ON_NULL_RETURN(evdev);
+
+   if (evdev->caps & E_INPUT_SEAT_KEYBOARD)
+     {
+        if (evdev->xkb.state) xkb_state_unref(evdev->xkb.state);
+
+        if (evdev->xkb.keymap) xkb_map_unref(evdev->xkb.keymap);
+     }
+
+   if (evdev->e_dev) g_object_unref(evdev->e_dev);
+   if (evdev->e_dev_list)
+     {
+        GList *glist = evdev->e_dev_list;
+        E_Device *e_dev;
+        while (glist)
+          {
+             e_dev = glist->data;
+             g_object_unref(e_dev);
+
+             glist = g_list_next(glist);
+          }
+     }
+
+   if (evdev->device) libinput_device_unref(evdev->device);
+
+   ecore_main_loop_thread_safe_call_async(_evdev_device_destroy_async_cb, evdev);
+}
+
 EINTERN Eina_List *
 e_input_seat_evdev_list_get(E_Input_Seat *seat)
 {