Support pipe communication between main thread and input thread 29/306829/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Thu, 8 Feb 2024 02:50:45 +0000 (11:50 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 28 Feb 2024 05:35:00 +0000 (14:35 +0900)
Change-Id: I583ee3e4a02a2d239b5a4476e1bba48f68142895
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/e_input_inputs.c
src/bin/e_input_intern.h
src/bin/e_main.c

index 963bf0a..a048ca2 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <glib.h>
 
+static int main_to_input_thread_pipe_fd[2] = {0, };
+
 static gboolean input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
 static gboolean input_thread_prepare(GSource *source, gint *time);
 
@@ -799,6 +801,39 @@ input_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
    return G_SOURCE_CONTINUE;
 }
 
+static gboolean
+_pipe_recv_handler(GIOChannel *source, GIOCondition condition, gpointer user_data)
+{
+   E_Input_Backend *input = user_data;
+   char *data;
+   int len;
+   E_Input_Thread_Request_Data order;
+
+   if (condition == G_IO_IN)
+     {
+        len = read(input->main_to_input_thread_pipe_fd[0], &order, sizeof(E_Input_Thread_Request_Data));
+        if (len <= 0)
+          return TRUE;
+
+        data = calloc(1, sizeof(char)*order.data_length);
+        len = read(input->main_to_input_thread_pipe_fd[0], data, order.data_length);
+        if (len <= 0)
+          {
+             free(data);
+             return TRUE;
+          }
+
+        if (order.safe_call_cb)
+          order.safe_call_cb(data);
+
+        free(data);
+     }
+   else if (condition == G_IO_ERR || condition == G_IO_HUP)
+     ERR("Error or hangup\n");
+
+   return TRUE;
+}
+
 static void
 input_thread_start(void *data, Ecore_Thread *th)
 {
@@ -806,6 +841,8 @@ input_thread_start(void *data, Ecore_Thread *th)
    E_Input_Backend *input;
    GMainContext *context = NULL;
    InputEventSource *input_event_source = NULL;
+   GIOChannel *_pipe_iochannel = NULL;
+   GSource *pipe_source = NULL;
 
    if (!(input = data)) return;
 
@@ -843,6 +880,11 @@ input_thread_start(void *data, Ecore_Thread *th)
    g_source_set_callback(&input_event_source->gsource, NULL, input, NULL);
    g_source_attach(&input_event_source->gsource, context);
 
+   _pipe_iochannel = g_io_channel_unix_new(input->main_to_input_thread_pipe_fd[0]);
+   pipe_source = g_io_create_watch(_pipe_iochannel, G_IO_IN);
+   g_source_set_callback(pipe_source, (GSourceFunc)_pipe_recv_handler, input, NULL);
+   g_source_attach(pipe_source, context);
+
    e_comp_wl_input_keymap_init();
    e_keyrouter_query_tizen_key_table();
 
@@ -1023,7 +1065,54 @@ EINTERN void e_input_thread_start()
    g_input_backend->input_thread = ecore_thread_feedback_run(input_thread_start, input_thread_feedback, input_thread_end, input_thread_cancel, g_input_backend, EINA_FALSE);
 }
 
+EINTERN void e_input_thread_init()
+{
+   if (pipe(main_to_input_thread_pipe_fd) != 0)
+     ERR("error in pipe\n");
+
+   if (g_input_backend)
+     {
+        g_input_backend->main_to_input_thread_pipe_fd[0] = main_to_input_thread_pipe_fd[0];
+        g_input_backend->main_to_input_thread_pipe_fd[1] = main_to_input_thread_pipe_fd[1];
+     }
+}
+
+EINTERN void e_input_thread_shutdown()
+{
+   EINA_SAFETY_ON_NULL_RETURN(g_input_backend);
+
+   close(g_input_backend->main_to_input_thread_pipe_fd[0]);
+   close(g_input_backend->main_to_input_thread_pipe_fd[1]);
+}
+
 EINTERN void e_input_thread_input_backend_set(E_Input_Backend *input)
 {
    g_input_backend = input;
+
+   if (g_input_backend->main_to_input_thread_pipe_fd[0] == 0)
+     {
+        g_input_backend->main_to_input_thread_pipe_fd[0] = main_to_input_thread_pipe_fd[0];
+        g_input_backend->main_to_input_thread_pipe_fd[1] = main_to_input_thread_pipe_fd[1];
+     }
+}
+
+EINTERN void
+e_input_thread_safe_call(E_Input_Thread_Safe_Call_Cb cb, void *data, size_t data_length)
+{
+   E_Input_Thread_Request_Data order;
+   order.safe_call_cb = cb;
+   order.data_length = data_length;
+
+   if (!cb) return;
+   if (!g_input_backend)
+     {
+        ERR("Not yet initialized\n");
+        return;
+     }
+
+   if (write(g_input_backend->main_to_input_thread_pipe_fd[1], &order, sizeof(E_Input_Thread_Request_Data)) == -1)
+     ERR("error when writing header in pipe\n");
+
+   if (write(g_input_backend->main_to_input_thread_pipe_fd[1], data, data_length) == -1)
+     ERR("error when writing data in pipe\n");
 }
index 13ff66b..5aa3e3e 100644 (file)
@@ -24,6 +24,13 @@ struct _E_Input_Coord
    int y;
 };
 
+typedef void (*E_Input_Thread_Safe_Call_Cb)(void *data);
+
+typedef struct {
+    E_Input_Thread_Safe_Call_Cb safe_call_cb;
+    unsigned int data_length;
+} E_Input_Thread_Request_Data;
+
 struct _E_Input_Seat
 {
    const char *name;
@@ -68,6 +75,8 @@ struct _E_Input_Backend
 
    GMainLoop *input_thread_loop;
    E_Input_Event_Source *event_source;
+
+   int main_to_input_thread_pipe_fd[2];
 };
 
 struct _E_Input_Evdev
@@ -215,6 +224,10 @@ EINTERN void e_input_boost_unlock(GMutex *mutex);
 EINTERN void e_input_thread_id_set(pid_t tid);
 EINTERN void e_input_thread_start();
 EINTERN void e_input_thread_input_backend_set(E_Input_Backend *input);
+EINTERN void e_input_thread_safe_call(E_Input_Thread_Safe_Call_Cb cb, void *data, size_t data_length);
+
+EINTERN void e_input_thread_init();
+EINTERN void e_input_thread_shutdown();
 
 EINTERN void e_input_device_output_changed(E_Input_Device *dev);
 
index d1f346e..7135834 100644 (file)
@@ -686,7 +686,10 @@ main(int argc, char **argv)
    _e_main_shutdown_push(e_keyrouter_shutdown);
 
    if (e_input_thread_mode_get())
-     e_input_thread_start();
+     {
+        e_input_thread_init();
+        e_input_thread_start();
+     }
 
    if (e_config->eom_enable)
      {