diff options
author | Sung-jae Park <nicesj.park@samsung.com> | 2015-08-04 16:32:25 +0900 |
---|---|---|
committer | Sung-jae Park <nicesj.park@samsung.com> | 2015-08-04 16:32:25 +0900 |
commit | be6f0dc4328628ce98c47ac970eac113ae9efb6a (patch) | |
tree | 835b1ad32ee28f36a1e57f2780745b0d0a8a2368 | |
parent | 481f592f26fa521d9aaa18082cdde745453c9af3 (diff) | |
download | com-core-tizen.tar.gz com-core-tizen.tar.bz2 com-core-tizen.zip |
Do not process the finalize in the nested call.HEADtizen_3.0.m2.a1_tv_releasetizen_3.0.m2.a1_mobile_releasesubmit/tizen_common/20151019.135620submit/tizen_common/20151015.190624submit/tizen/20150917.014254submit/tizen/20150916.141025accepted/tizen/tv/20150917.041120accepted/tizen/mobile/20150917.041057tizen
Change-Id: I056b5953cff53c6053412b56c6be4a31aa7c33ba
-rw-r--r-- | include/com-core_internal.h | 8 | ||||
-rw-r--r-- | packaging/libcom-core.spec | 4 | ||||
-rw-r--r-- | src/com-core.c | 58 | ||||
-rw-r--r-- | src/com-core_thread.c | 29 |
4 files changed, 69 insertions, 30 deletions
diff --git a/include/com-core_internal.h b/include/com-core_internal.h index 667a48d..dc5591b 100644 --- a/include/com-core_internal.h +++ b/include/com-core_internal.h @@ -16,6 +16,12 @@ */ extern void invoke_con_cb_list(int server_fd, int handle, guint id, void *data, int watch); -extern void invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int watch); + +/** + * @note + * This function will returns 0 if it is processed peacefully, + * But 1 will be returned if it is already called. (in case of the nested call) + */ +extern int invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int watch); /* End of a file */ diff --git a/packaging/libcom-core.spec b/packaging/libcom-core.spec index 0ff41a3..a1d1a48 100644 --- a/packaging/libcom-core.spec +++ b/packaging/libcom-core.spec @@ -1,6 +1,6 @@ Name: libcom-core -Summary: Library for the light-weight IPC -Version: 1.0.1 +Summary: Library for the light-weight IPC +Version: 1.0.2 Release: 1 Group: Base/IPC License: Apache-2.0 diff --git a/src/com-core.c b/src/com-core.c index 68793b9..5869ba9 100644 --- a/src/com-core.c +++ b/src/com-core.c @@ -40,6 +40,7 @@ static struct { struct dlist *watch_list; struct dlist *conn_cb_list; struct dlist *disconn_cb_list; + struct dlist *disconn_fd_list; enum processing_event_callback { PROCESSING_NONE = 0x0, PROCESSING_DISCONNECTION = 0x01, @@ -49,6 +50,7 @@ static struct { .watch_list = NULL, .conn_cb_list = NULL, .disconn_cb_list = NULL, + .disconn_fd_list = NULL, .processing_event_callback = PROCESSING_NONE, }; @@ -127,13 +129,18 @@ static void watch_item_destroy_all(int socket_fd) dlist_foreach_safe(s_info.watch_list, l, n, item) { if (item->server_fd == socket_fd) { DbgPrint("Watch item removed: %d/%d\n", item->server_fd, item->fd); - /*! - * \WARN + /** + * @WARN * If the watch_list item is removed from disconnected * callback, this list loop can be broken. * Please check it again. */ - invoke_disconn_cb_list(item->fd, 0, 0, 0); + (void)invoke_disconn_cb_list(item->fd, 0, 0, 0); + /** + * @note + * socket_fd will be closed by caller. + * so we do not need to close it at here. + */ s_info.watch_list = dlist_remove(s_info.watch_list, l); if (item->id > 0) { @@ -172,16 +179,34 @@ HAPI void invoke_con_cb_list(int server_fd, int handle, guint id, void *data, in s_info.processing_event_callback &= ~PROCESSING_CONNECTION; } -HAPI void invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int watch) +HAPI int invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int watch) { struct dlist *l; struct dlist *n; struct evtdata *cbdata; + void *item; + + /** + * @note + * Basically, the disconnected handler will be called once. + * But from the disconnected callback, someone calls fini(fd), + * this disconnection callback can be called again. + * So we have to check whether this is a nested call or not. + * If it is a nested call, we should not do anything anymore. + */ + dlist_foreach_safe(s_info.disconn_fd_list, l, n, item) { + if (handle == (int)((long)item)) { /*!< Cast for 64 bits */ + DbgPrint("nested destroyer %d\n", handle); + return 1; + } + } + + s_info.disconn_fd_list = dlist_append(s_info.disconn_fd_list, (void *)((long)handle)); /*!< Cast for 64 bits */ s_info.processing_event_callback |= PROCESSING_DISCONNECTION; dlist_foreach_safe(s_info.disconn_cb_list, l, n, cbdata) { - /*! - * \NOTE + /** + * @note * cbdata->deleted must has to be checked before call the function and * return from the function call. */ @@ -197,6 +222,9 @@ HAPI void invoke_disconn_cb_list(int handle, int remove_id, int remove_data, int ErrPrint("Failed to destroy watch item\n"); } } + + dlist_remove_data(s_info.disconn_fd_list, (void *)((long)handle)); /*!< Cast for 64 bits */ + return 0; } static int validate_handle(int fd) @@ -223,14 +251,14 @@ static gboolean client_cb(GIOChannel *src, GIOCondition cond, gpointer data) if (!(cond & G_IO_IN)) { DbgPrint("Client is disconencted\n"); - invoke_disconn_cb_list(client_fd, 0, 1, 1); + (void)invoke_disconn_cb_list(client_fd, 0, 1, 1); secure_socket_destroy_handle(client_fd); return FALSE; } if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) { DbgPrint("Client connection is lost\n"); - invoke_disconn_cb_list(client_fd, 0, 1, 1); + (void)invoke_disconn_cb_list(client_fd, 0, 1, 1); secure_socket_destroy_handle(client_fd); return FALSE; } @@ -238,14 +266,14 @@ static gboolean client_cb(GIOChannel *src, GIOCondition cond, gpointer data) ret = cbdata->service_cb(client_fd, cbdata->data); if (ret < 0) { DbgPrint("service callback returns %d < 0\n", ret); - invoke_disconn_cb_list(client_fd, 0, 1, 1); + (void)invoke_disconn_cb_list(client_fd, 0, 1, 1); secure_socket_destroy_handle(client_fd); return FALSE; } /* Check whether the socket FD is closed or not */ if (!validate_handle(client_fd)) { - invoke_disconn_cb_list(client_fd, 0, 1, 1); + (void)invoke_disconn_cb_list(client_fd, 0, 1, 1); secure_socket_destroy_handle(client_fd); return FALSE; } @@ -736,16 +764,18 @@ EAPI void *com_core_del_event_callback(enum com_core_event_type type, int (*cb)( EAPI int com_core_server_destroy(int handle) { DbgPrint("Close server handle[%d]\n", handle); - invoke_disconn_cb_list(handle, 1, 1, 1); - secure_socket_destroy_handle(handle); + if (invoke_disconn_cb_list(handle, 1, 1, 1) == 0) { + secure_socket_destroy_handle(handle); + } return 0; } EAPI int com_core_client_destroy(int handle) { DbgPrint("Close client handle[%d]\n", handle); - invoke_disconn_cb_list(handle, 1, 1, 1); - secure_socket_destroy_handle(handle); + if (invoke_disconn_cb_list(handle, 1, 1, 1) == 0) { + secure_socket_destroy_handle(handle); + } return 0; } diff --git a/src/com-core_thread.c b/src/com-core_thread.c index 42a3cbd..3bb457f 100644 --- a/src/com-core_thread.c +++ b/src/com-core_thread.c @@ -189,7 +189,7 @@ static inline void terminate_thread(struct tcb *tcb) if (status != 0) { ErrPrint("Join: %s\n", strerror(status)); } else { - ErrPrint("Thread returns: %d\n", (int)res); + ErrPrint("Thread returns: %d\n", (int)((long)res)); } dlist_foreach_safe(tcb->chunk_list, l, n, chunk) { @@ -503,7 +503,7 @@ static gboolean evt_pipe_cb(GIOChannel *src, GIOCondition cond, gpointer data) errout: DbgPrint("Disconnecting\n"); - invoke_disconn_cb_list(tcb->handle, 0, 0, 0); + (void)invoke_disconn_cb_list(tcb->handle, 0, 0, 0); terminate_thread(tcb); tcb_destroy(tcb); return FALSE; @@ -672,7 +672,7 @@ static gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer data) } if (ret != 0) { ErrPrint("Thread creation failed: %s\n", strerror(ret)); - invoke_disconn_cb_list(tcb->handle, 0, 0, 0); + (void)invoke_disconn_cb_list(tcb->handle, 0, 0, 0); secure_socket_destroy_handle(tcb->handle); tcb_destroy(tcb); server_destroy(server); @@ -770,7 +770,7 @@ EAPI int com_core_thread_client_create(const char *addr, int is_sync, int (*serv } if (ret != 0) { ErrPrint("Thread creation failed: %s\n", strerror(ret)); - invoke_disconn_cb_list(tcb->handle, 0, 0, 0); + (void)invoke_disconn_cb_list(tcb->handle, 0, 0, 0); secure_socket_destroy_handle(tcb->handle); tcb_destroy(tcb); return -EFAULT; @@ -876,7 +876,7 @@ EAPI int com_core_thread_client_create_by_fd(int client_fd, int is_sync, int (*s } if (ret != 0) { ErrPrint("Thread creation failed: %s\n", strerror(ret)); - invoke_disconn_cb_list(tcb->handle, 0, 0, 0); + (void)invoke_disconn_cb_list(tcb->handle, 0, 0, 0); secure_socket_destroy_handle(tcb->handle); tcb_destroy(tcb); return -EFAULT; @@ -1151,9 +1151,10 @@ EAPI int com_core_thread_server_destroy(int handle) continue; } - invoke_disconn_cb_list(handle, 0, 0, 0); - terminate_thread(tcb); - tcb_destroy(tcb); + if (invoke_disconn_cb_list(handle, 0, 0, 0) == 0) { + terminate_thread(tcb); + tcb_destroy(tcb); + } return 0; } @@ -1162,8 +1163,9 @@ EAPI int com_core_thread_server_destroy(int handle) continue; } - invoke_disconn_cb_list(handle, 0, 0, 0); - server_destroy(server); + if (invoke_disconn_cb_list(handle, 0, 0, 0) == 0) { + server_destroy(server); + } return 0; } @@ -1183,9 +1185,10 @@ EAPI int com_core_thread_client_destroy(int handle) return -ENOENT; } - invoke_disconn_cb_list(handle, 0, 0, 0); - terminate_thread(tcb); - tcb_destroy(tcb); + if (invoke_disconn_cb_list(handle, 0, 0, 0) == 0) { + terminate_thread(tcb); + tcb_destroy(tcb); + } return 0; } |