From 2735c957022c72d376ea885d8dcb187781bb0fd2 Mon Sep 17 00:00:00 2001 From: Sung-jae Park Date: Fri, 18 Apr 2014 11:36:27 +0900 Subject: [PATCH] Update the deleted/updated callback call routine. While processing the updated/deleted callback, any item can be deleted. Using in_use flag, if there is deleting request while processing callback list, don't delete item directly just toggle the deleted flag. After callback call, check the deleted flag. if the deleted flag is toggled, Then delete it from the list safely. Change-Id: Ifa69564bfdd83fbdeb01bbf59ab2635105020274 --- packaging/com.samsung.data-provider-slave.spec | 2 +- src/lb.c | 6 +++ src/update_monitor.c | 70 +++++++++++++++++++------- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/packaging/com.samsung.data-provider-slave.spec b/packaging/com.samsung.data-provider-slave.spec index 977816d..c268624 100644 --- a/packaging/com.samsung.data-provider-slave.spec +++ b/packaging/com.samsung.data-provider-slave.spec @@ -2,7 +2,7 @@ Name: com.samsung.data-provider-slave Summary: Plugin type livebox service provider -Version: 0.13.4 +Version: 0.14.0 Release: 1 Group: HomeTF/Livebox License: Flora diff --git a/src/lb.c b/src/lb.c index 64fef83..946f88d 100644 --- a/src/lb.c +++ b/src/lb.c @@ -945,6 +945,11 @@ static int file_updated_cb(const char *filename, void *data, int over) item = data; + if (item->deleteme) { + DbgPrint("Item is in deleting process. (%s)\n", filename); + goto out; + } + ESTIMATE_START(item->inst->id); ret = util_get_filesize(filename); @@ -979,6 +984,7 @@ static int file_updated_cb(const char *filename, void *data, int over) } ESTIMATE_END(item->inst->id); +out: return output_handler(item); } diff --git a/src/update_monitor.c b/src/update_monitor.c index 4027d22..f848fa1 100644 --- a/src/update_monitor.c +++ b/src/update_monitor.c @@ -40,6 +40,7 @@ struct cb_item { char *filename; int (*cb)(const char *filename, void *data, int over); void *data; + int deleted; }; static struct info { @@ -48,14 +49,52 @@ static struct info { Ecore_Fd_Handler *handler; Eina_List *update_list; Eina_List *delete_list; + unsigned int update_list_in_use; + unsigned int delete_list_in_use; } s_info = { .ifd = -EINVAL, .iwd = -EINVAL, .handler = NULL, .update_list = NULL, .delete_list = NULL, + .update_list_in_use = 0, + .delete_list_in_use = 0, }; +static void *update_item_destroy(struct cb_item *item, Eina_List *l) +{ + void *data; + + if (s_info.update_list_in_use) { + item->deleted = 1; + data = item->data; + } else { + s_info.update_list = eina_list_remove_list(s_info.update_list, l); + data = item->data; + free(item->filename); + free(item); + } + + return data; +} + +static void *delete_item_destroy(struct cb_item *item, Eina_List *l) +{ + void *data; + + if (s_info.delete_list_in_use == 1) { + item->deleted = 1; + data = item->data; + } else { + s_info.delete_list = eina_list_remove_list(s_info.delete_list, l); + data = item->data; + free(item->filename); + free(item); + } + + return data; +} + static Eina_Bool monitor_cb(void *data, Ecore_Fd_Handler *handler) { int fd; @@ -216,10 +255,11 @@ HAPI int update_monitor_trigger_update_cb(const char *filename, int over) struct cb_item *item; int cnt = 0; + s_info.update_list_in_use = 1; EINA_LIST_FOREACH_SAFE(s_info.update_list, l, n, item) { - if (!strcmp(filename, item->filename) && item->cb(filename, item->data, over) == EXIT_FAILURE) { - /* Item can be deleted from the callback, so need to check existence */ - if (eina_list_data_find(s_info.update_list, item)) { + if (!strcmp(filename, item->filename)) { + if (item->deleted || item->cb(filename, item->data, over) == EXIT_FAILURE || item->deleted) { + /* Item can be deleted from the callback, so need to check existence */ s_info.update_list = eina_list_remove_list(s_info.update_list, l); free(item->filename); free(item); @@ -227,6 +267,7 @@ HAPI int update_monitor_trigger_update_cb(const char *filename, int over) cnt++; } } + s_info.update_list_in_use = 0; return cnt == 0 ? LB_STATUS_ERROR_INVALID : LB_STATUS_SUCCESS; } @@ -238,17 +279,20 @@ HAPI int update_monitor_trigger_delete_cb(const char *filename, int over) struct cb_item *item; int cnt = 0; + s_info.delete_list_in_use = 1; EINA_LIST_FOREACH_SAFE(s_info.delete_list, l, n, item) { - if (!strcmp(filename, item->filename) && item->cb(filename, item->data, over) == EXIT_FAILURE) { - /* Item can be deleted from the callback, so need to check existence. */ - if (eina_list_data_find(s_info.delete_list, item)) { + if (!strcmp(filename, item->filename)) { + /* delete should be checked before call the callback & after call the callback */ + if (item->deleted || item->cb(filename, item->data, over) == EXIT_FAILURE || item->deleted) { s_info.delete_list = eina_list_remove_list(s_info.delete_list, l); free(item->filename); free(item); } + cnt++; } } + s_info.delete_list_in_use = 0; return cnt == 0 ? LB_STATUS_ERROR_INVALID : LB_STATUS_SUCCESS; } @@ -307,15 +351,10 @@ HAPI void *update_monitor_del_update_cb(const char *filename, { Eina_List *l; struct cb_item *item; - void *data; EINA_LIST_FOREACH(s_info.update_list, l, item) { if (item->cb == cb && !strcmp(item->filename, filename)) { - s_info.update_list = eina_list_remove_list(s_info.update_list, l); - data = item->data; - free(item->filename); - free(item); - return data; + return update_item_destroy(item, l); } } @@ -327,15 +366,10 @@ HAPI void *update_monitor_del_delete_cb(const char *filename, { Eina_List *l; struct cb_item *item; - void *data; EINA_LIST_FOREACH(s_info.delete_list, l, item) { if (item->cb == cb && !strcmp(item->filename, filename)) { - s_info.delete_list = eina_list_remove_list(s_info.delete_list, l); - data = item->data; - free(item->filename); - free(item); - return data; + return delete_item_destroy(item, l); } } -- 2.7.4