Fix fd event handling 06/223106/2
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 23 Jan 2020 02:04:14 +0000 (11:04 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Thu, 23 Jan 2020 02:12:13 +0000 (11:12 +0900)
- Uses GIOChannel instead of GSource

Change-Id: Iaf999693e8da5b0830f015435d0ebf37accab91a
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
inc/launchpad_io_channel.h [new file with mode: 0644]
src/launchpad.c
src/launchpad_io_channel.c [new file with mode: 0644]
src/log_private.h

index ad32426..5239b49 100755 (executable)
@@ -146,6 +146,7 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES
        src/launchpad_debug.c
        src/launchpad_signal.c
        src/launchpad_config.c
+       src/launchpad_io_channel.c
        )
 ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES})
 
diff --git a/inc/launchpad_io_channel.h b/inc/launchpad_io_channel.h
new file mode 100644 (file)
index 0000000..6498fb3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+typedef enum {
+       IO_IN = 0x01,
+       IO_OUT = 0x02,
+       IO_PRI = 0x04,
+       IO_ERR = 0x08,
+       IO_HUP = 0x10,
+       IO_NVAL = 0x20,
+} io_condition_e;
+
+typedef bool (*io_channel_event_cb)(int fd, io_condition_e condition,
+               void *user_data);
+
+typedef struct io_channel_s *io_channel_h;
+
+io_channel_h _io_channel_create(int fd, io_condition_e condition,
+               io_channel_event_cb, void *user_data);
+
+void _io_channel_destroy(io_channel_h channel);
index e751fbb..b847c2c 100755 (executable)
@@ -44,6 +44,7 @@
 #include "launchpad_common.h"
 #include "launchpad_config.h"
 #include "launchpad_debug.h"
+#include "launchpad_io_channel.h"
 #include "launchpad_signal.h"
 #include "launchpad_types.h"
 #include "loader_info.h"
@@ -84,7 +85,6 @@ typedef struct {
        int send_fd;
        int hydra_fd;
        int last_exec_time;
-       guint source;
        guint timer;
        char *loader_path;
        char *loader_extra;
@@ -105,8 +105,9 @@ typedef struct {
        guint live_timer;
        int state;
        bool is_hydra;
-       guint pollfd;
-       guint hydra_pollfd;
+       io_channel_h client_channel;
+       io_channel_h channel;
+       io_channel_h hydra_channel;
 } candidate_process_context_t;
 
 typedef struct {
@@ -152,6 +153,11 @@ static sequencer __sequencer;
 static int MEMORY_STATUS_LOW;
 static int MEMORY_STATUS_NORMAL;
 
+static io_channel_h __logger_channel;
+static io_channel_h __label_monitor_channel;
+static io_channel_h __sigchild_channel;
+static io_channel_h __launchpad_channel;
+
 static candidate_process_context_t *__add_slot(int type, int loader_id,
                int caller_pid, const char *loader_path, const char *extra,
                int detection_method, int activation_method,
@@ -787,7 +793,7 @@ static void __reset_slot(candidate_process_context_t *cpc)
        cpc->send_fd = -1;
        cpc->prepared = false;
        cpc->pid = CANDIDATE_NONE;
-       cpc->source = 0;
+       cpc->client_channel = NULL;
        cpc->timer = 0;
        cpc->live_timer = 0;
 }
@@ -804,8 +810,8 @@ static void __dispose_candidate_process(candidate_process_context_t *cpc)
        }
        if (cpc->live_timer > 0)
                g_source_remove(cpc->live_timer);
-       if (cpc->source > 0)
-               g_source_remove(cpc->source);
+       if (cpc->client_channel)
+               _io_channel_destroy(cpc->client_channel);
        if (cpc->timer > 0)
                g_source_remove(cpc->timer);
        if (cpc->send_fd > 0)
@@ -1216,172 +1222,57 @@ static int __launchpad_pre_init(int argc, char **argv)
        return fd;
 }
 
-static void __destroy_poll_data(gpointer data)
-{
-       free(data);
-}
-
-static gboolean __glib_check(GSource *src)
-{
-       GSList *fd_list;
-       GPollFD *tmp;
-
-       fd_list = src->poll_fds;
-       do {
-               tmp = (GPollFD *) fd_list->data;
-               if ((tmp->revents & (G_IO_IN | G_IO_PRI | G_IO_HUP |
-                                               G_IO_NVAL)))
-                       return TRUE;
-               fd_list = fd_list->next;
-       } while (fd_list);
-
-       return FALSE;
-}
-
-static gboolean __glib_dispatch(GSource *src, GSourceFunc callback,
-               gpointer data)
-{
-       return callback(data);
-}
-
-static gboolean __glib_prepare(GSource *src, gint *timeout)
-{
-       return FALSE;
-}
-
-static void __glib_finalize(GSource *src)
-{
-       GSList *fd_list;
-       GPollFD *gpollfd;
-
-       fd_list = src->poll_fds;
-       do {
-               gpollfd = (GPollFD *)fd_list->data;
-               close(gpollfd->fd);
-               g_free(gpollfd);
-
-               fd_list = fd_list->next;
-       } while (fd_list);
-}
-
-static GSourceFuncs funcs = {
-       .prepare = __glib_prepare,
-       .check = __glib_check,
-       .dispatch = __glib_dispatch,
-       .finalize = __glib_finalize
-};
-
-static guint __poll_fd(int fd, gushort events, GSourceFunc func, int type,
-               int loader_id)
+static bool __handle_loader_client_event(int fd, io_condition_e cond,
+               void *data)
 {
-       int r;
-       GPollFD *gpollfd;
-       GSource *src;
-       loader_context_t *lc;
-
-       src = g_source_new(&funcs, sizeof(GSource));
-       if (!src) {
-               _E("out of memory");
-               return 0;
-       }
-
-       gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
-       if (!gpollfd) {
-               _E("out of memory");
-               g_source_destroy(src);
-               return 0;
-       }
-
-       gpollfd->events = events;
-       gpollfd->fd = fd;
-
-       lc = malloc(sizeof(loader_context_t));
-       if (lc == NULL) {
-               g_free(gpollfd);
-               g_source_destroy(src);
-               return 0;
-       }
-
-       lc->gpollfd = gpollfd;
-       lc->type = type;
-       lc->loader_id = loader_id;
-
-       g_source_add_poll(src, gpollfd);
-       g_source_set_callback(src, func,
-                       (gpointer) lc, __destroy_poll_data);
-       g_source_set_priority(src, G_PRIORITY_DEFAULT);
-
-       r = g_source_attach(src, NULL);
-       if (r  == 0) {
-               g_free(gpollfd);
-               g_source_destroy(src);
-               return 0;
-       }
-
-       return r;
-}
-
-static gboolean __handle_loader_client_event(gpointer data)
-{
-       loader_context_t *lc = (loader_context_t *) data;
-       int type = lc->type;
-       int loader_id = lc->loader_id;
-       gushort revents = lc->gpollfd->revents;
-       candidate_process_context_t *cpc = __find_slot(type, loader_id);
+       candidate_process_context_t *cpc = data;
 
        if (cpc == NULL)
-               return G_SOURCE_REMOVE;
+               return false;
 
-       if (revents & (G_IO_HUP | G_IO_NVAL)) {
-               SECURE_LOGE("Type %d candidate process was " \
+       if (cond & (IO_HUP | IO_NVAL)) {
+               SECURE_LOGE("Type %d candidate process was "
                                "(POLLHUP|POLLNVAL), pid: %d",
                                cpc->type, cpc->pid);
                cpc->pid = CANDIDATE_NONE;
                __dispose_candidate_process(cpc);
                __prepare_candidate_process(cpc->type, cpc->loader_id);
-               return G_SOURCE_REMOVE;
+               return false;
        }
 
-       return G_SOURCE_CONTINUE;
+       return true;
+
 }
 
-static gboolean __handle_hydra_client_event(gpointer data)
+static bool __handle_hydra_client_event(int fd, io_condition_e cond,
+               void *data)
 {
-       loader_context_t *lc = (loader_context_t *)data;
-       int type = lc->type;
-       int loader_id = lc->loader_id;
-       gushort revents = lc->gpollfd->revents;
-       candidate_process_context_t *cpc = __find_slot(type, loader_id);
+       candidate_process_context_t *cpc = data;
 
        if (cpc == NULL)
-               return G_SOURCE_REMOVE;
+               return false;
 
-       if (revents & (G_IO_HUP | G_IO_NVAL)) {
-               SECURE_LOGE("Type %d hydra process was " \
+       if (cond & (IO_HUP | IO_NVAL)) {
+               SECURE_LOGE("Type %d hydra process was "
                                "(POLLHUP|POLLNVAL), pid: %d",
                                cpc->type, cpc->hydra_pid);
                __dispose_hydra_process(cpc);
                __prepare_candidate_process(cpc->type, cpc->loader_id);
-               return G_SOURCE_REMOVE;
+               return false;
        }
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
-static gboolean __handle_loader_event(gpointer data)
+static bool __handle_loader_event(int fd, io_condition_e cond, void *data)
 {
-       loader_context_t *lc = (loader_context_t *) data;
-       int fd = lc->gpollfd->fd;
-       int type = lc->type;
-       int loader_id = lc->loader_id;
+       candidate_process_context_t *cpc = data;
        int client_fd;
        int client_pid;
        int ret;
 
-       candidate_process_context_t *cpc = __find_slot(type, loader_id);
-
        if (cpc == NULL)
-               return G_SOURCE_REMOVE;
+               return false;
 
        if (!cpc->prepared) {
                ret = __accept_candidate_process(fd, &client_fd, &client_pid);
@@ -1394,12 +1285,13 @@ static gboolean __handle_loader_event(gpointer data)
                        cpc->prepared = true;
                        cpc->send_fd = client_fd;
 
-                       SECURE_LOGD("Type %d candidate process was connected," \
-                                       " pid: %d", type, cpc->pid);
-                       cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP,
-                                       __handle_loader_client_event, type,
-                                       loader_id);
-                       if (cpc->source == 0)
+                       SECURE_LOGD("Type %d candidate process was connected, "
+                                       "pid: %d", cpc->type, cpc->pid);
+                       cpc->client_channel = _io_channel_create(client_fd,
+                                       IO_IN | IO_HUP,
+                                       __handle_loader_client_event,
+                                       cpc);
+                       if (!cpc->client_channel)
                                close(client_fd);
                }
        } else {
@@ -1407,36 +1299,32 @@ static gboolean __handle_loader_event(gpointer data)
                _E("Refused candidate process connection");
        }
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
-static gboolean __handle_hydra_event(gpointer data)
+static bool __handle_hydra_event(int fd, io_condition_e cond, void *data)
 {
-       loader_context_t *lc = (loader_context_t *) data;
-       int fd = lc->gpollfd->fd;
-       int type = lc->type;
-       int loader_id = lc->loader_id;
+       candidate_process_context_t *cpc = data;
        int client_fd;
        int client_pid;
        int ret;
 
-       candidate_process_context_t *cpc = __find_slot(type, loader_id);
-
        if (cpc == NULL)
-               return G_SOURCE_REMOVE;
+               return false;
 
        if (!cpc->prepared) {
                ret = __accept_candidate_process(fd, &client_fd, &client_pid);
                if (ret >= 0) {
                        cpc->hydra_fd = client_fd;
 
-                       SECURE_LOGD("Type %d hydra process was connected," \
-                                       " pid: %d", type, cpc->hydra_pid);
+                       SECURE_LOGD("Type %d hydra process was connected,"
+                                       " pid: %d", cpc->type, cpc->hydra_pid);
 
-                       cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP,
-                                       __handle_hydra_client_event, type,
-                                       loader_id);
-                       if (cpc->source == 0)
+                       cpc->client_channel = _io_channel_create(client_fd,
+                                       IO_IN | IO_HUP,
+                                       __handle_hydra_client_event,
+                                       cpc);
+                       if (!cpc->client_channel)
                                close(client_fd);
                }
        } else {
@@ -1444,14 +1332,12 @@ static gboolean __handle_hydra_event(gpointer data)
                _E("Refused hydra process connection");
        }
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
-static gboolean __handle_sigchild(gpointer data)
+static bool __handle_sigchild(int fd, io_condition_e cond, void *data)
 {
        candidate_process_context_t *cpc;
-       loader_context_t *lc = (loader_context_t *) data;
-       int fd = lc->gpollfd->fd;
        struct signalfd_siginfo siginfo;
        ssize_t s;
        char *appid;
@@ -1498,15 +1384,15 @@ static gboolean __handle_sigchild(gpointer data)
                }
        } while (s > 0);
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
-static gboolean __handle_label_monitor(gpointer data)
+static bool __handle_label_monitor(int fd, io_condition_e cond, void *data)
 {
        candidate_process_context_t *cpc;
        GList *iter = candidate_slot_list;
 
-       _D("__handle_label_monitor()");
+       _D("%s()", __FUNCTION__);
        security_manager_app_labels_monitor_process(label_monitor);
 
        while (iter) {
@@ -1525,7 +1411,7 @@ static gboolean __handle_label_monitor(gpointer data)
                iter = g_list_next(iter);
        }
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
 static float __interpolator(float input, int cpu_max, int cpu_min)
@@ -1894,10 +1780,8 @@ static void __update_slot_state(candidate_process_context_t *cpc, int method)
        }
 }
 
-static gboolean __handle_launch_event(gpointer data)
+static bool __handle_launch_event(int fd, io_condition_e cond, void *data)
 {
-       loader_context_t *lc = (loader_context_t *) data;
-       int fd = lc->gpollfd->fd;
        bundle *kb = NULL;
        app_pkt_t *pkt = NULL;
        appinfo_t *menu_info = NULL;
@@ -2075,7 +1959,7 @@ end:
 
        traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
 
-       return G_SOURCE_CONTINUE;
+       return true;
 }
 
 static void __destroy_slot(candidate_process_context_t *cpc)
@@ -2083,11 +1967,11 @@ static void __destroy_slot(candidate_process_context_t *cpc)
        if (!cpc)
                return;
 
-       if (cpc->hydra_pollfd)
-               g_source_remove(cpc->hydra_pollfd);
+       if (cpc->hydra_channel)
+               _io_channel_destroy(cpc->hydra_channel);
 
-       if (cpc->pollfd)
-               g_source_remove(cpc->pollfd);
+       if (cpc->channel)
+               _io_channel_destroy(cpc->channel);
 
        if (cpc->loader_extra)
                free(cpc->loader_extra);
@@ -2138,7 +2022,6 @@ static candidate_process_context_t *__create_slot(int type, int loader_id,
        cpc->send_fd = -1;
        cpc->hydra_fd = -1;
        cpc->last_exec_time = 0;
-       cpc->source = 0;
        cpc->timer = 0;
        cpc->detection_method = detection_method;
        cpc->timeout_val = timeout_val;
@@ -2176,9 +2059,9 @@ static candidate_process_context_t *__add_slot(int type, int loader_id,
 {
        candidate_process_context_t *cpc;
        int fd;
-       guint pollfd;
+       io_channel_h channel;
        int hydra_fd;
-       guint hydra_pollfd;
+       io_channel_h hydra_channel;
 
        if (__find_slot(type, loader_id) != NULL)
                return NULL;
@@ -2202,15 +2085,14 @@ static candidate_process_context_t *__add_slot(int type, int loader_id,
                return NULL;
        }
 
-       pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_loader_event,
-                       cpc->type, cpc->loader_id);
-       if (pollfd == 0) {
+       channel = _io_channel_create(fd, IO_IN, __handle_loader_event, cpc);
+       if (!channel) {
                close(fd);
                __destroy_slot(cpc);
                return NULL;
        }
 
-       cpc->pollfd = pollfd;
+       cpc->channel = channel;
 
        if (is_hydra) {
                hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id);
@@ -2218,22 +2100,19 @@ static candidate_process_context_t *__add_slot(int type, int loader_id,
                        _E("[launchpad] Listening the socket to " \
                                        "the type %d hydra process failed.",
                                        cpc->type);
-                       close(fd);
                        __destroy_slot(cpc);
                        return NULL;
                }
 
-               hydra_pollfd = __poll_fd(hydra_fd, G_IO_IN,
-                               (GSourceFunc)__handle_hydra_event,
-                               cpc->type, cpc->loader_id);
-               if (hydra_pollfd == 0) {
+               hydra_channel = _io_channel_create(hydra_fd, IO_IN,
+                               __handle_hydra_event, cpc);
+               if (!hydra_channel) {
                        close(hydra_fd);
-                       close(fd);
                        __destroy_slot(cpc);
                        return NULL;
                }
 
-               cpc->hydra_pollfd = hydra_pollfd;
+               cpc->hydra_channel = hydra_channel;
        }
 
 
@@ -2267,7 +2146,6 @@ static int __remove_slot(int type, int loader_id)
 static int __init_launchpad_fd(int argc, char **argv)
 {
        int fd = -1;
-       guint pollfd;
 
        fd = __launchpad_pre_init(argc, argv);
        if (fd < 0) {
@@ -2275,9 +2153,9 @@ static int __init_launchpad_fd(int argc, char **argv)
                return -1;
        }
 
-       pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_launch_event, 0,
-                       0);
-       if (pollfd == 0) {
+       __launchpad_channel = _io_channel_create(fd, IO_IN,
+                       __handle_launch_event, NULL);
+       if (!__launchpad_channel) {
                close(fd);
                return -1;
        }
@@ -2288,7 +2166,6 @@ static int __init_launchpad_fd(int argc, char **argv)
 static int __init_sigchild_fd(void)
 {
        int fd = -1;
-       guint pollfd;
 
        fd = _signal_get_sigchld_fd();
        if (fd < 0) {
@@ -2296,8 +2173,9 @@ static int __init_sigchild_fd(void)
                return -1;
        }
 
-       pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_sigchild, 0, 0);
-       if (pollfd == 0) {
+       __sigchild_channel = _io_channel_create(fd, IO_IN,
+                       __handle_sigchild, NULL);
+       if (!__sigchild_channel) {
                close(fd);
                return -1;
        }
@@ -2309,7 +2187,6 @@ static int __init_label_monitor_fd(void)
 {
        int r;
        int fd = -1;
-       guint pollfd;
 
        r = security_manager_app_labels_monitor_init(&label_monitor);
        if (r != SECURITY_MANAGER_SUCCESS)
@@ -2325,9 +2202,9 @@ static int __init_label_monitor_fd(void)
                goto err;
        }
 
-       pollfd = __poll_fd(fd, G_IO_IN,
-                       (GSourceFunc)__handle_label_monitor, 0, 0);
-       if (pollfd == 0)
+       __label_monitor_channel = _io_channel_create(fd, IO_IN,
+                       __handle_label_monitor, NULL);
+       if (!__label_monitor_channel)
                goto err;
 
        return 0;
@@ -2590,18 +2467,16 @@ static int __register_vconf_events(void)
        return 0;
 }
 
-static gboolean __handle_logger(gpointer data)
+static bool __handle_logger(int fd, io_condition_e cond, void *data)
 {
-       loader_context_t *lc = (loader_context_t *)data;
-       int fd = lc->gpollfd->fd;
-       app_pkt_t *pkt = NULL;
+       app_pkt_t *pkt;
        struct ucred cr;
        int clifd = -1;
 
        pkt = _accept_recv_pkt_raw(fd, &clifd, &cr);
        if (!pkt) {
                _E("Failed to receive the packet");
-               return G_SOURCE_CONTINUE;
+               return true;
        }
 
        if (getuid() != cr.uid) {
@@ -2615,20 +2490,18 @@ static gboolean __handle_logger(gpointer data)
        }
 
        SECURE_LOGE("[%d] %s", cr.pid, (const char *)pkt->data);
-
 end:
        if (clifd != -1)
                close(clifd);
-       if (pkt)
-               free(pkt);
 
-       return G_SOURCE_CONTINUE;
+       free(pkt);
+
+       return true;
 }
 
 static int __init_logger_fd(void)
 {
        int fd;
-       guint pollfd;
 
        fd = _create_server_sock(LAUNCHPAD_LOGGER_SOCK);
        if (fd < 0) {
@@ -2636,8 +2509,8 @@ static int __init_logger_fd(void)
                return -1;
        }
 
-       pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_logger, 0, 0);
-       if (pollfd == 0) {
+       __logger_channel = _io_channel_create(fd, IO_IN, __handle_logger, NULL);
+       if (!__logger_channel) {
                close(fd);
                return -1;
        }
@@ -2713,9 +2586,21 @@ static void __after_loop(void)
        _launcher_info_unload(launcher_info_list);
        _config_fini();
 
+       if (__label_monitor_channel)
+               _io_channel_destroy(__label_monitor_channel);
+
        if (label_monitor)
                security_manager_app_labels_monitor_finish(label_monitor);
 
+       if (__logger_channel)
+               _io_channel_destroy(__logger_channel);
+
+       if (__launchpad_channel)
+               _io_channel_destroy(__launchpad_channel);
+
+       if (__sigchild_channel)
+               _io_channel_destroy(__sigchild_channel);
+
        __sequencer_fini();
 }
 
diff --git a/src/launchpad_io_channel.c b/src/launchpad_io_channel.c
new file mode 100644 (file)
index 0000000..f20cb92
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "launchpad_io_channel.h"
+#include "log_private.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+struct io_channel_s {
+       GIOChannel *io;
+       guint tag;
+       int fd;
+       io_channel_event_cb callback;
+       void *user_data;
+};
+
+struct io_condition_s {
+       io_condition_e io_cond;
+       GIOCondition g_io_cond;
+};
+
+static struct io_condition_s __cond_map[] = {
+       {
+               .io_cond = IO_IN,
+               .g_io_cond = G_IO_IN
+       },
+       {
+               .io_cond = IO_OUT,
+               .g_io_cond = G_IO_OUT
+       },
+       {
+               .io_cond = IO_PRI,
+               .g_io_cond = G_IO_PRI
+       },
+       {
+               .io_cond = IO_ERR,
+               .g_io_cond = G_IO_ERR
+       },
+       {
+               .io_cond = IO_HUP,
+               .g_io_cond = G_IO_HUP
+       },
+       {
+               .io_cond = IO_NVAL,
+               .g_io_cond = G_IO_NVAL,
+       }
+};
+
+static io_condition_e __convert_g_io_condition(GIOCondition cond)
+{
+       io_condition_e condition = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
+               if (__cond_map[i].g_io_cond & cond)
+                       condition |= __cond_map[i].io_cond;
+       }
+
+       return condition;
+}
+
+static GIOCondition __convert_io_condition(io_condition_e cond)
+{
+       GIOCondition condition = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(__cond_map); i++) {
+               if (__cond_map[i].io_cond & cond)
+                       condition |= __cond_map[i].g_io_cond;
+       }
+
+       return condition;
+}
+
+static gboolean __io_event_cb(GIOChannel *source, GIOCondition condition,
+               gpointer data)
+{
+       io_channel_h channel = (io_channel_h)data;
+       io_condition_e cond = __convert_g_io_condition(condition);
+
+       if (!channel->callback(channel->fd, cond, channel->user_data))
+               return G_SOURCE_REMOVE;
+
+       return G_SOURCE_CONTINUE;
+}
+
+io_channel_h _io_channel_create(int fd, io_condition_e cond,
+               io_channel_event_cb callback, void *user_data)
+{
+       struct io_channel_s *channel;
+
+       if (fd < 3 || !callback) {
+               _E("Invalid parameter");
+               return NULL;
+       }
+
+       channel = calloc(1, sizeof(struct io_channel_s));
+       if (!channel) {
+               _E("Out of memory");
+               return NULL;
+       }
+
+       channel->io = g_io_channel_unix_new(fd);
+       if (!channel->io) {
+               _E("Failed to create GIOChannel");
+               _io_channel_destroy(channel);
+               return NULL;
+       }
+
+       channel->tag = g_io_add_watch(channel->io, __convert_io_condition(cond),
+                       __io_event_cb, channel);
+       if (!channel->tag) {
+               _E("Failed to add GIO watch");
+               _io_channel_destroy(channel);
+               return NULL;
+       }
+
+       channel->fd = fd;
+       channel->callback = callback;
+       channel->user_data = user_data;
+
+       return channel;
+}
+
+void _io_channel_destroy(io_channel_h channel)
+{
+       if (!channel)
+               return;
+
+       if (channel->tag)
+               g_source_remove(channel->tag);
+
+       if (channel->io)
+               g_io_channel_unref(channel->io);
+
+       if (channel->fd)
+               close(channel->fd);
+
+       free(channel);
+}
index f214b78..c3b0662 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #endif
 #define LOG_TAG "LAUNCHPAD"
 
+#ifdef _E
+#undef _E
+#endif
 #define _E(fmt, arg...) LOGE(fmt, ##arg)
+
+#ifdef _D
+#undef _D
+#endif
 #define _D(fmt, arg...) LOGD(fmt, ##arg)
+
+#ifdef _W
+#undef _W
+#endif
 #define _W(fmt, arg...) LOGW(fmt, ##arg)
+
+#ifdef _I
+#undef _I
+#endif
 #define _I(fmt, arg...) LOGI(fmt, ##arg)
 
 #endif /* __LOG_PRIVATE_H__ */