Use g_aync_queue instead of epoll for handling of instance connection event 68/234968/13
authorYoungHun Kim <yh8004.kim@samsung.com>
Mon, 1 Jun 2020 07:04:58 +0000 (16:04 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Tue, 2 Jun 2020 23:56:39 +0000 (08:56 +0900)
Change-Id: I3f801559dcc202c68b761a062e04263a73f1c11a

core/src/muse_core.c
packaging/mused.spec
server/include/muse_server_connection.h
server/include/muse_server_private.h
server/src/muse_server_connection.c
server/src/muse_server_private.c
server/src/muse_server_system.c

index 1b91d5a..92cd6d6 100644 (file)
@@ -808,10 +808,8 @@ int muse_core_get_process_cpu_usage(int pid)
        if (fp) {
                while (fgets(buf, MUSE_MSG_LEN_MAX, fp)) {
                        LOGW("%s", buf);
-                       if (idx++ == 1) {
+                       if (idx++ == 1)
                                cpu = atoi(g_strstrip(buf));
-                               break;
-                       }
                }
 
                if (pclose(fp) == -1)
index d3ad8aa..5200dcf 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mused
 Summary:    A multimedia daemon
-Version:    0.3.114
+Version:    0.3.115
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index e972b53..aa53b40 100644 (file)
@@ -38,19 +38,16 @@ typedef enum {
 } ms_connection_state_e;
 
 typedef struct ms_connection {
-       int epfd;
-       struct epoll_event events[MS_EVENT_MAX];
        int instance_count[MUSE_MODULE_MAX];
-       GQueue *instance_queue;
+       GQueue *instance_q;
+       GAsyncQueue *msg_aq;
        GMutex lock;
-       GCond cond;
 } ms_connection_t;
 
 void ms_connection_init(ms_connection_t *connection);
 void ms_connection_deinit(ms_connection_t *connection);
 int ms_connection_register(muse_module_h m);
 int ms_connection_unregister(muse_module_h m);
-gboolean ms_connection_get_state(ms_connection_state_e *state, int *out_fd);
 void ms_connection_lock(ms_connection_t *connection);
 void ms_connection_unlock(ms_connection_t *connection);
 
index b755c84..481f076 100644 (file)
@@ -63,6 +63,11 @@ typedef enum {
 
 typedef struct _muse_server *muse_server_h;
 
+typedef struct connection_msg {
+       gboolean thread_stop;
+       int cmd;
+} ms_diag_msg_t;
+
 typedef struct _muse_server {
        int msg_fd;
        int data_fd;
@@ -71,7 +76,6 @@ typedef struct _muse_server {
        int retval;
        int pid;
        int cpu_threshold;
-       gint running;
        tbm_bufmgr bufmgr;
        GMainLoop *main_loop;
        GThread *diag_idle_state_thread;
@@ -106,7 +110,7 @@ muse_server_h ms_get_instance(void);
 gboolean ms_check_module_idx(int idx);
 ms_module_t *ms_get_module_instance(int idx);
 int ms_deinit(void);
-void ms_check_cpu_memory(int pid);
+void ms_check_cpu_memory(void);
 void ms_new(void);
 int ms_open_lockfile(void);
 void ms_run(void);
@@ -126,6 +130,7 @@ void ms_diag_thread_create(void);
 void ms_diag_thread_destroy(void);
 gboolean ms_create_ready_file(void);
 void ms_remove_ready_file(void);
+const char *ms_get_command_string(int cmd);
 
 #ifdef __cplusplus
 }
index 8f995cf..f66ca96 100644 (file)
 
 #define EPOLL_ERR -1
 
-static const char *connection_cmd[API_MAX] = {
-       "connect",
-       "disconnect"
-};
-
+static void _ms_connection_destroy_async_queue(gpointer data);
 static void _ms_connection_module_instance_info(muse_module_h m, ms_connection_t *connection, GQueue *queue, int cmd);
 
+static void _ms_connection_destroy_async_queue(gpointer data)
+{
+       ms_diag_msg_t *dm = (ms_diag_msg_t *)data;
+
+       LOGI("diag msg (%p) free", dm);
+       g_free(dm);
+}
+
 static void _ms_connection_module_instance_info(muse_module_h m, ms_connection_t *connection, GQueue *queue, int cmd)
 {
        muse_module_h connecting_m;
        char pids[MUSE_MSG_LEN_MAX] = {'\0',};
        char pid[MUSE_PARAM_MAX] = {'\0',};
        int idx, len;
+       ms_diag_msg_t *dm;
 
        muse_return_if_fail(m);
        muse_return_if_fail(connection);
@@ -57,17 +62,21 @@ static void _ms_connection_module_instance_info(muse_module_h m, ms_connection_t
 
        strncpy(ms_get_instance()->instance_pid_info, pids, MUSE_MSG_LEN_MAX);
 
+       dm = g_new0(ms_diag_msg_t, 1);
+
+       dm->cmd = cmd;
+
+       g_async_queue_push(connection->msg_aq, (gpointer)dm);
+
        LOGW("total number of modules = %d ( %s) - %s %p from pid %d %s client (count %d)",
-               len, ms_get_instance()->instance_pid_info,connection_cmd[cmd], m, m->pid,
+               len, ms_get_instance()->instance_pid_info, ms_get_command_string(cmd), m, m->pid,
                ms_config_get_host_name(m->idx), connection->instance_count[m->idx]);
 }
 
 int ms_connection_register(muse_module_h m)
 {
-       int fd, caution_instance;
+       int caution_instance;
        GQueue *queue;
-       struct epoll_event event = { 0 };
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
        ms_connection_t *connection = NULL;
 
        LOGD("Enter");
@@ -77,22 +86,12 @@ int ms_connection_register(muse_module_h m)
        connection = ms_get_instance()->connection;
 
        muse_return_val_if_fail(connection, MM_ERROR_INVALID_ARGUMENT);
-       muse_return_val_if_fail(connection->instance_queue, MM_ERROR_INVALID_ARGUMENT);
+       muse_return_val_if_fail(connection->instance_q, MM_ERROR_INVALID_ARGUMENT);
        muse_return_val_if_fail(m, MM_ERROR_INVALID_ARGUMENT);
 
        ms_connection_lock(connection);
 
-       queue = connection->instance_queue;
-
-       fd = m->ch[MUSE_CHANNEL_MSG].sock_fd;
-
-       event.events = EPOLLIN;
-       event.data.ptr = GINT_TO_POINTER(fd);
-
-       if (epoll_ctl(connection->epfd, EPOLL_CTL_ADD, fd, &event) == EPOLL_ERR) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("epoll ctl error - %s", err_msg);
-       }
+       queue = connection->instance_q;
 
        g_queue_push_tail(queue, (gpointer)m);
 
@@ -131,11 +130,11 @@ int ms_connection_unregister(muse_module_h m)
        connection = ms_get_instance()->connection;
 
        muse_return_val_if_fail(connection, MM_ERROR_INVALID_ARGUMENT);
-       muse_return_val_if_fail(connection->instance_queue, MM_ERROR_INVALID_ARGUMENT);
+       muse_return_val_if_fail(connection->instance_q, MM_ERROR_INVALID_ARGUMENT);
 
        ms_connection_lock(connection);
 
-       queue = connection->instance_queue;
+       queue = connection->instance_q;
 
        fd = m->ch[MUSE_CHANNEL_MSG].sock_fd;
 
@@ -144,9 +143,6 @@ int ms_connection_unregister(muse_module_h m)
 
        _ms_connection_module_instance_info(m, connection, queue, API_DESTROY);
 
-       LOGI("[%d] g_cond_signal", fd);
-       g_cond_signal(&connection->cond);
-
        ms_connection_unlock(connection);
 
        LOGD("Leave");
@@ -154,73 +150,6 @@ int ms_connection_unregister(muse_module_h m)
        return MM_ERROR_NONE;
 }
 
-gboolean ms_connection_get_state(ms_connection_state_e *state, int *out_fd)
-{
-       int idx, fd, ep_fd, fd_count, errsv;
-       struct epoll_event *p_event;
-       struct timeval tv_c, tv_s, tv_r;
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
-       ms_connection_t *connection = NULL;
-
-       muse_return_val_if_fail(ms_get_instance(), MM_ERROR_UNKNOWN);
-       muse_return_val_if_fail(out_fd, MM_ERROR_INVALID_ARGUMENT);
-
-       connection = ms_get_instance()->connection;
-
-       muse_return_val_if_fail(connection, FALSE);
-
-       ep_fd = connection->epfd;
-
-       do { /* We have to execute epoll_wait again in case of error of EINTR */
-               gettimeofday(&tv_s, NULL);
-               fd_count = epoll_wait(ep_fd, connection->events, MS_EVENT_MAX, MS_TIMEOUT_MSEC);
-               if (fd_count < 0) {
-                       errsv = errno;
-                       strerror_r(errsv, err_msg, MUSE_MSG_LEN_MAX);
-                       LOGE("[%d : %d] errno : %d (%s)", ep_fd, muse_core_fd_is_valid(ep_fd), errsv, err_msg);
-               }
-               gettimeofday(&tv_c, NULL);
-       } while (fd_count < 0 && errsv == EINTR);
-
-       if (fd_count == 0) { /* There is no muse instance during timeout, which is not error case */
-               timersub(&tv_c, &tv_s, &tv_r);
-               if (tv_r.tv_sec != MS_TIMEOUT_SEC)
-                       usleep(10000); /* 10ms */
-               return FALSE;
-       } else if (fd_count < 0) { /* When an error occurs, epoll_wait() returns -1 */
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("[%d : %d] %s", ep_fd, muse_core_fd_is_valid(connection->epfd), err_msg);
-               return FALSE;
-       }
-
-       for (idx = 0; idx < fd_count; idx++) {
-               p_event = &connection->events[idx];
-               fd = GPOINTER_TO_INT(p_event->data.ptr);
-
-               if (p_event->events == EPOLLIN) {
-                       LOGI("CONNECTED [epoll fd : %d] [client fd : %d]", ep_fd, fd);
-
-                       p_event->events = EPOLLRDHUP;
-                       if (muse_core_fd_is_valid(fd) && epoll_ctl(ep_fd, EPOLL_CTL_MOD, fd, p_event) == EPOLL_ERR) {
-                               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-                               LOGE("epoll ctl error - %s [%d] [fd : %d]", err_msg, errno, fd);
-                       }
-                       *state = MUSE_CONNECTION_STATE_CONNECTED;
-               } else if (p_event->events & EPOLLRDHUP) {
-                       LOGI("DISCONNECTED [epoll fd : %d] [client fd : %d]", ep_fd, fd);
-
-                       if (muse_core_fd_is_valid(fd) && epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, p_event) == EPOLL_ERR) {
-                               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-                               LOGE("epoll ctl error - %s [%d] [fd : %d]", err_msg, errno, fd);
-                       }
-                       *state = MUSE_CONNECTION_STATE_DISCONNECTED;
-               }
-               *out_fd = fd;
-       }
-
-       return TRUE;
-}
-
 void ms_connection_lock(ms_connection_t *connection)
 {
        muse_return_if_fail(connection);
@@ -237,12 +166,13 @@ void ms_connection_deinit(ms_connection_t *connection)
 {
        muse_return_if_fail(connection);
 
-       g_queue_free(connection->instance_queue);
-       connection->instance_queue = NULL;
+       g_queue_free(connection->instance_q);
+       connection->instance_q = NULL;
 
-       g_mutex_clear(&connection->lock);
+       g_async_queue_unref(connection->msg_aq);
+       connection->msg_aq = NULL;
 
-       close(connection->epfd);
+       g_mutex_clear(&connection->lock);
 
        g_free(connection);
 }
@@ -251,11 +181,11 @@ void ms_connection_init(ms_connection_t *connection)
 {
        muse_return_if_fail(connection);
 
-       connection->epfd = epoll_create(MS_EVENT_MAX);
-       muse_return_if_fail(muse_core_fd_is_valid(connection->epfd));
+       connection->instance_q = g_queue_new();
+       muse_return_if_fail(connection->instance_q);
 
-       connection->instance_queue = g_queue_new();
-       muse_return_if_fail(connection->instance_queue);
+       connection->msg_aq = g_async_queue_new_full(_ms_connection_destroy_async_queue);
+       muse_return_if_fail(connection->msg_aq);
 
        g_mutex_init(&connection->lock);
 }
index de5956d..6119022 100644 (file)
@@ -65,7 +65,6 @@ static int _ms_new(muse_channel_e channel);
 static int _ms_get_pid(int fd);
 static void _ms_get_module_addr(int fd, intptr_t *module_addr);
 static void _ms_check_idle_state(void);
-static void _ms_check_connection_event(void);
 static gpointer _ms_diag_check_idle_state_thread(gpointer data);
 static gpointer _ms_diag_check_connection_event_thread(gpointer data);
 static void _ms_lock_state(void);
@@ -318,7 +317,7 @@ static gboolean _ms_connection_handler(GIOChannel *source, GIOCondition conditio
 
                ms_connection_lock(connection);
 
-               instance_queue = connection->instance_queue;
+               instance_queue = connection->instance_q;
                len = g_queue_get_length(instance_queue);
 
                m = (muse_module_h)module_addr;
@@ -425,7 +424,7 @@ static void _ms_check_idle_state(void)
 
        ms_connection_lock(connection);
 
-       instance_number = g_queue_get_length(connection->instance_queue);
+       instance_number = g_queue_get_length(connection->instance_q);
 
        if (timeout >= ms_config_get_log_period() * period_idx) {
                LOGW("total number of modules = %d ( %s)", instance_number, muse_server->instance_pid_info);
@@ -443,24 +442,6 @@ static void _ms_check_idle_state(void)
        }
 }
 
-static void _ms_check_connection_event(void)
-{
-       ms_connection_state_e state = MUSE_CONNECTION_STATE_INVALID;
-       int fd = -1;
-
-       muse_return_if_fail(muse_server);
-
-       if (ms_connection_get_state(&state, &fd)) {
-               gettimeofday(&muse_server->tv_s, NULL);
-               if (state == MUSE_CONNECTION_STATE_CONNECTED) {
-                       /* will be updated about connection at the next patch */
-               } else if (state == MUSE_CONNECTION_STATE_DISCONNECTED) {
-                       LOGD("Diagnostic thread checks the memory of idle");
-                       ms_check_cpu_memory(fd);
-               }
-       }
-}
-
 static gpointer _ms_diag_check_idle_state_thread(gpointer data)
 {
        int idle_state_wait_time = ms_config_get_idle_state_wait_time();
@@ -478,10 +459,29 @@ static gpointer _ms_diag_check_idle_state_thread(gpointer data)
 
 static gpointer _ms_diag_check_connection_event_thread(gpointer data)
 {
+       ms_diag_msg_t *dm = NULL;
        muse_return_val_if_fail(muse_server, NULL);
 
-       while (ms_is_server_ready())
-               _ms_check_connection_event();
+       while (ms_is_server_ready()) {
+               dm = (ms_diag_msg_t *)g_async_queue_pop(ms_get_instance()->connection->msg_aq);
+               if (!dm)
+                       continue;
+
+               LOGD("[%p] pop message (thread stop ? %d [%s])", dm, dm->thread_stop, ms_get_command_string(dm->cmd));
+
+               if (dm->thread_stop) {
+                       g_free(dm);
+                       break;
+               }
+
+               if (dm->cmd == API_CREATE) {
+                       /* can be updated if connection at the next patch */
+               } else if (dm->cmd == API_DESTROY) {
+                       ms_check_cpu_memory();
+               }
+
+               g_free(dm);
+       }
 
        return NULL;
 }
@@ -628,10 +628,18 @@ void ms_diag_thread_create(void)
 
 void ms_diag_thread_destroy(void)
 {
+       ms_diag_msg_t *dm;
+
        muse_return_if_fail(muse_server);
 
        LOGD("Enter");
 
+       dm = g_new0(ms_diag_msg_t, 1);
+
+       dm->thread_stop = TRUE;
+       LOGI("[%p] g_async_queue_push", dm);
+       g_async_queue_push_front(muse_server->connection->msg_aq, (gpointer)dm);
+
        if (muse_server->diag_idle_state_thread) {
                g_thread_join(muse_server->diag_idle_state_thread);
                muse_server->diag_idle_state_thread = NULL;
@@ -1057,7 +1065,7 @@ int ms_deinit(void)
        return retval;
 }
 
-void ms_check_cpu_memory(int fd)
+void ms_check_cpu_memory(void)
 {
        int used_pss, memory_threshold, cpu_usage;
        char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
@@ -1070,12 +1078,7 @@ void ms_check_cpu_memory(int fd)
 
        ms_connection_lock(connection);
 
-       while (muse_core_fd_is_valid(fd)) {
-               g_cond_wait(&connection->cond, &connection->lock);
-               LOGI("[%d] is_valid : %d", fd, muse_core_fd_is_valid(fd));
-       }
-
-       if (g_queue_is_empty(connection->instance_queue) && ms_is_server_ready()) {
+       if (g_queue_is_empty(connection->instance_q) && ms_is_server_ready()) {
                used_pss = ms_system_get_memory_usage(muse_server->pid);
                cpu_usage = muse_core_get_process_cpu_usage(muse_server->pid);
 
@@ -1096,7 +1099,7 @@ void ms_check_cpu_memory(int fd)
 
                muse_core_remove_all_fd_table();
        } else {
-               LOGI("skip cpu memory check due to instance queue length : %d", g_queue_get_length(connection->instance_queue));
+               LOGI("skip cpu memory check due to instance queue length : %d", g_queue_get_length(connection->instance_q));
        }
 
        ms_connection_unlock(connection);
@@ -1323,3 +1326,15 @@ void ms_remove_ready_file(void)
 #endif
 }
 
+const char *ms_get_command_string(int cmd)
+{
+       if (cmd == API_CREATE)
+               return "connect";
+       else if (cmd == API_DESTROY)
+               return "disconnect";
+       else
+               LOGE("Invalid value of cmd (%d)", cmd);
+
+       return "Invalid value of cmd";
+}
+
index 744e805..bb391d7 100644 (file)
@@ -89,7 +89,6 @@ static void _ms_poweroff_state_changed_cb(GDBusConnection *con, const gchar *sen
                        const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data)
 {
        int val_int = 0;
-       GQueue *queue;
        ms_cmd_dispatcher_info_t dispatch;
        ms_system_t *system = NULL;
        ms_connection_t *connection = NULL;
@@ -125,11 +124,9 @@ static void _ms_poweroff_state_changed_cb(GDBusConnection *con, const gchar *sen
 
        ms_connection_lock(connection);
 
-       queue = connection->instance_queue;
-
        dispatch.cmd = MUSE_MODULE_COMMAND_SHUTDOWN;
 
-       g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
+       g_queue_foreach(connection->instance_q, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
 
        ms_connection_unlock(connection);
 
@@ -166,7 +163,6 @@ static void _ms_system_unsubscribe_external_storage_state_change(void)
 static void _ms_external_storage_state_changed_cb(int storage_id, storage_dev_e dev, storage_state_e state, const char *fstype,
                        const char *fsuuid, const char *mount_path, bool primary, int flags, void *user_data)
 {
-       GQueue *queue;
        ms_cmd_dispatcher_info_t dispatch;
        ms_system_t *system = (ms_system_t *)user_data;
        ms_connection_t *connection = NULL;
@@ -198,15 +194,13 @@ static void _ms_external_storage_state_changed_cb(int storage_id, storage_dev_e
 
        ms_connection_lock(connection);
 
-       queue = connection->instance_queue;
-
        dispatch.cmd = MUSE_MODULE_COMMAND_EXTERNAL_STORAGE_STATE_CHANGED;
 
        dispatch.storage.id = storage_id;
        dispatch.storage.state = state;
        dispatch.storage.path = mount_path;
 
-       g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
+       g_queue_foreach(connection->instance_q, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
 
        ms_connection_unlock(connection);
 
@@ -248,7 +242,6 @@ static void _ms_system_unsubscribe_resource_manager_state_change(void)
 static void _ms_resource_manager_owner_name_changed_cb(GDBusConnection *con, const gchar *sender_name, const gchar *object_path,
                        const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data)
 {
-       GQueue *queue;
        ms_cmd_dispatcher_info_t dispatch;
        ms_system_t *system = NULL;
        ms_connection_t *connection = NULL;
@@ -279,11 +272,9 @@ static void _ms_resource_manager_owner_name_changed_cb(GDBusConnection *con, con
 
        ms_connection_lock(connection);
 
-       queue = connection->instance_queue;
-
        dispatch.cmd = MUSE_MODULE_COMMAND_RESOURCE_MANAGER_SHUTDOWN;
 
-       g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
+       g_queue_foreach(connection->instance_q, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
        LOGE("resource manager shutdown");
 
        ms_connection_unlock(connection);