#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);
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");
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);
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;
_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");
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);
{
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);
}
{
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);
}
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);
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;
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);
}
}
-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();
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;
}
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;
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',};
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);
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);
#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";
+}
+
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;
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);
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;
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);
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;
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);