From 415fadc0557943434ceea849fb9d2423a62f5a2d Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Wed, 23 Nov 2016 09:41:50 +0900 Subject: [PATCH] Clear sender socket info when receive socket disconnected event Change-Id: Ic4a3d75aaa6a0c487c54315b84c0b4e83039d457 Signed-off-by: Hyunho Kang Signed-off-by: jusung son --- src/message-port.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/src/message-port.c b/src/message-port.c index 523027a..216dc5d 100755 --- a/src/message-port.c +++ b/src/message-port.c @@ -131,6 +131,8 @@ typedef struct port_list_info { int send_sock_fd; int watcher_id; bool exist; + GIOChannel *gio_read; + int g_src_id; } port_list_info_s; static void __callback_info_free(gpointer data) @@ -419,6 +421,42 @@ out: return remote_app_info; } +static void __clear_disconnect_socket(port_list_info_s *port_info) +{ + GError *error = NULL; + + if (port_info == NULL) + return; + _LOGI("__clear_disconnect_socket : fd [%d]", port_info->send_sock_fd); + + if (port_info->gio_read != NULL) { + g_io_channel_shutdown(port_info->gio_read, TRUE, &error); + if (error) { + _LOGE("g_io_channel_shutdown error : %s", error->message); + g_error_free(error); + } + g_io_channel_unref(port_info->gio_read); + port_info->gio_read = NULL; + } + + if (port_info->g_src_id != 0) { + g_source_remove(port_info->g_src_id); + port_info->g_src_id = 0; + } + port_info->send_sock_fd = 0; +} + +static gboolean __socket_disconnect_handler(GIOChannel *gio, + GIOCondition cond, + gpointer data) +{ + /* It's sender socket's gio channel so, only EOF can be received */ + port_list_info_s *port_info = (port_list_info_s *)data; + _LOGI("__socket_disconnect_handler %d", cond); + __clear_disconnect_socket(port_info); + return FALSE; +} + static void __watch_remote_port_info(port_list_info_s *port_info) { if (port_info == NULL) @@ -843,7 +881,7 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation if (returned_fds == NULL) { _LOGE("fail to get fds"); __callback_info_free(callback_info); - return -1; + return false; } fd = returned_fds[0]; @@ -854,7 +892,7 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation if (!callback_info->gio_read) { _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf))); __callback_info_free(callback_info); - return -1; + return false; } callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP, @@ -862,7 +900,7 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation if (callback_info->g_src_id == 0) { _LOGE("fail to add watch on socket"); __callback_info_free(callback_info); - return -1; + return false; } callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(mi->local_id)); @@ -871,7 +909,7 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation if (head_callback_info == NULL) { _LOGE("fail to alloc head_callback_info"); __callback_info_free(callback_info); - return -1; + return false; } head_callback_info->local_id = 0; head_callback_info->remote_app_id = NULL; @@ -1384,22 +1422,26 @@ int __message_port_send_async(int sockfd, bundle *kb, const char *local_port, if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) { _LOGE("write local_port fail"); - return MESSAGEPORT_ERROR_IO_ERROR; + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; } if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) { _LOGE("write is_bidirection fail"); - return MESSAGEPORT_ERROR_IO_ERROR; + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; } if (__write_socket(sockfd, (char *)&local_trusted, sizeof(local_trusted), &nb) != MESSAGEPORT_ERROR_NONE) { _LOGE("write local_trusted fail"); - return MESSAGEPORT_ERROR_IO_ERROR; + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; } if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) { _LOGE("write kb_data fail"); ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; } out: if (kb_data) @@ -1426,6 +1468,7 @@ static int __message_port_send_message(const char *remote_appid, const char *rem GError *err = NULL; GVariant *body = NULL; int sock_pair[2] = {0,}; + char buf[1024]; ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info); if (ret != MESSAGEPORT_ERROR_NONE) @@ -1442,7 +1485,6 @@ static int __message_port_send_message(const char *remote_appid, const char *rem goto out; } } - __watch_remote_port_info(port_info); if (port_info->send_sock_fd > 0) { ret = __message_port_send_async(port_info->send_sock_fd, message, @@ -1480,12 +1522,28 @@ static int __message_port_send_message(const char *remote_appid, const char *rem _LOGE("g_unix_fd_list_append [%s]", err->message); ret = MESSAGEPORT_ERROR_IO_ERROR; g_error_free(err); - close(sock_pair[SOCK_PAIR_SENDER]); - close(sock_pair[SOCK_PAIR_RECEIVER]); goto out; } + port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER]; close(sock_pair[SOCK_PAIR_RECEIVER]); + sock_pair[SOCK_PAIR_RECEIVER] = 0; + + port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd); + if (!port_info->gio_read) { + _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf))); + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; + } + + port_info->g_src_id = g_io_add_watch(port_info->gio_read, G_IO_IN | G_IO_HUP, + __socket_disconnect_handler, (gpointer)port_info); + if (port_info->g_src_id == 0) { + _LOGE("fail to add watch on socket"); + ret = MESSAGEPORT_ERROR_IO_ERROR; + goto out; + } + } } @@ -1505,7 +1563,7 @@ static int __message_port_send_message(const char *remote_appid, const char *rem ret = MESSAGEPORT_ERROR_IO_ERROR; goto out; } - + __watch_remote_port_info(port_info); } @@ -1517,6 +1575,13 @@ out: if (fd_list) g_object_unref(fd_list); + if (ret != MESSAGEPORT_ERROR_NONE) { + __clear_disconnect_socket(port_info); + if (sock_pair[SOCK_PAIR_SENDER]) + close(sock_pair[SOCK_PAIR_SENDER]); + if (sock_pair[SOCK_PAIR_RECEIVER]) + close(sock_pair[SOCK_PAIR_RECEIVER]); + } return ret; } -- 2.7.4