Merge branch 'tizen_2.2' of ssh://review.tizendev.org:29418/apps/livebox/data-provide...
[platform/framework/web/data-provider-slave.git] / src / lb.c
index 11a675c..1d82a88 100644 (file)
--- a/src/lb.c
+++ b/src/lb.c
 
 int errno;
 
+#define UPDATE_ITEM_DELETED    (-1)
+#define UPDATE_INVOKED         (-2)
+#define UPDATE_NOT_INVOKED     (0)
+
 struct item {
        Ecore_Timer *timer;
        struct instance *inst;
@@ -60,7 +64,7 @@ struct item {
 
 static struct info {
        Eina_List *item_list;
-       struct item *update;
+       Eina_List *update_list;
        Eina_List *pending_list;
        Ecore_Timer *pending_timer;
        Eina_List *pd_open_pending_list;
@@ -71,7 +75,7 @@ static struct info {
        int pending_timer_freezed;
 } s_info  = {
        .item_list = NULL,
-       .update = NULL,
+       .update_list = NULL,
        .pending_list = NULL,
        .pending_timer = NULL,
        .pd_open_pending_list = NULL,
@@ -98,8 +102,9 @@ static void pending_timer_freeze(void)
 static void pending_timer_thaw(void)
 {
        DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
-       if (!s_info.pending_timer_freezed)
+       if (!s_info.pending_timer_freezed) {
                return;
+       }
 
        s_info.pending_timer_freezed--;
        if (s_info.pending_timer && !s_info.pending_timer_freezed) {
@@ -121,8 +126,9 @@ static inline int pd_is_opened(const char *pkgname)
 
        i = 0;
        EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
-               if (pkgname && !strcmp(pkgname, tmp))
+               if (pkgname && !strcmp(pkgname, tmp)) {
                        return 1;
+               }
 
                i++;
        }
@@ -135,20 +141,26 @@ static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
        struct item *item;
 
        item = eina_list_nth(s_info.pd_open_pending_list, 0);
-       if (!item)
+       if (!item) {
                goto cleanout;
+       }
 
-       if (s_info.update)
+       if (eina_list_data_find(s_info.update_list, item)) {
                return ECORE_CALLBACK_RENEW;
+       }
 
        s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
        /*!
         * \note
         * To prevent from checking the is_updated function
         */
-       (void)updator_cb(item);
-       if (s_info.pd_open_pending_list)
+       if (updator_cb(item) == ECORE_CALLBACK_CANCEL) {
+               /* Item is destroyed */
+       }
+
+       if (s_info.pd_open_pending_list) {
                return ECORE_CALLBACK_RENEW;
+       }
 
 cleanout:
        s_info.pd_open_pending_timer = NULL;
@@ -160,20 +172,26 @@ static Eina_Bool pended_cmd_consumer_cb(void *data)
        struct item *item;
 
        item = eina_list_nth(s_info.pending_list, 0);
-       if (!item)
+       if (!item) {
                goto cleanout;
+       }
 
-       if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0)
+       if (eina_list_data_find(s_info.update_list, item) || pd_is_opened(item->inst->item->pkgname) < 0) {
                return ECORE_CALLBACK_RENEW;
+       }
 
        s_info.pending_list = eina_list_remove(s_info.pending_list, item);
        /*!
         * \note
         * To prevent from checking the is_updated function
         */
-       (void)updator_cb(item);
-       if (s_info.pending_list)
+       if (updator_cb(item) == ECORE_CALLBACK_CANCEL) {
+               /* item is destroyed */
+       }
+
+       if (s_info.pending_list) {
                return ECORE_CALLBACK_RENEW;
+       }
 
 cleanout:
        s_info.pending_timer = NULL;
@@ -183,8 +201,9 @@ cleanout:
 
 static inline __attribute__((always_inline)) int activate_pending_consumer(void)
 {
-       if (s_info.pending_timer)
+       if (s_info.pending_timer) {
                return 0;
+       }
 
        s_info.pending_timer = ecore_timer_add(0.000001f, pended_cmd_consumer_cb, NULL);
        if (!s_info.pending_timer) {
@@ -196,16 +215,18 @@ static inline __attribute__((always_inline)) int activate_pending_consumer(void)
         * Do not increase the freezed counter.
         * Just freeze the timer.
         */
-       if (s_info.pending_timer_freezed)
+       if (s_info.pending_timer_freezed) {
                ecore_timer_freeze(s_info.pending_timer);
+       }
 
        return 0;
 }
 
 static inline void deactivate_pending_consumer(void)
 {
-       if (!s_info.pending_timer)
+       if (!s_info.pending_timer) {
                return;
+       }
 
        ecore_timer_del(s_info.pending_timer);
        s_info.pending_timer = NULL;
@@ -214,8 +235,9 @@ static inline void deactivate_pending_consumer(void)
 
 static inline void deactivate_pd_open_pending_consumer(void)
 {
-       if (!s_info.pd_open_pending_timer)
+       if (!s_info.pd_open_pending_timer) {
                return;
+       }
 
        ecore_timer_del(s_info.pd_open_pending_timer);
        s_info.pd_open_pending_timer = NULL;
@@ -223,8 +245,9 @@ static inline void deactivate_pd_open_pending_consumer(void)
 
 static inline int __attribute__((always_inline)) activate_pd_open_pending_consumer(void)
 {
-       if (s_info.pd_open_pending_timer)
+       if (s_info.pd_open_pending_timer) {
                return 0;
+       }
 
        s_info.pd_open_pending_timer = ecore_timer_add(0.000001f, pd_open_pended_cmd_consumer_cb, NULL);
        if (!s_info.pd_open_pending_timer) {
@@ -243,19 +266,22 @@ static inline void migrate_to_pd_open_pending_list(const char *pkgname)
        int cnt = 0;
 
        EINA_LIST_FOREACH_SAFE(s_info.pending_list, l, n, item) {
-               if (strcmp(pkgname, item->inst->item->pkgname))
+               if (strcmp(pkgname, item->inst->item->pkgname)) {
                        continue;
+               }
 
                s_info.pending_list = eina_list_remove(s_info.pending_list, item);
                s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
                cnt++;
        }
 
-       if (s_info.pd_open_pending_list)
+       if (s_info.pd_open_pending_list) {
                activate_pd_open_pending_consumer();
+       }
 
-       if (!s_info.pending_list)
+       if (!s_info.pending_list) {
                deactivate_pending_consumer();
+       }
 }
 
 static inline void migrate_to_pending_list(const char *pkgname)
@@ -266,19 +292,22 @@ static inline void migrate_to_pending_list(const char *pkgname)
        int cnt = 0;
 
        EINA_LIST_FOREACH_SAFE(s_info.pd_open_pending_list, l, n, item) {
-               if (strcmp(pkgname, item->inst->item->pkgname))
+               if (strcmp(pkgname, item->inst->item->pkgname)) {
                        continue;
+               }
 
                s_info.pd_open_pending_list = eina_list_remove(s_info.pd_open_pending_list, item);
                s_info.pending_list = eina_list_append(s_info.pending_list, item);
                cnt++;
        }
 
-       if (s_info.pending_list)
+       if (s_info.pending_list) {
                activate_pending_consumer();
+       }
 
-       if (!s_info.pd_open_pending_list)
+       if (!s_info.pd_open_pending_list) {
                deactivate_pd_open_pending_consumer();
+       }
 }
 
 static inline int is_pended_item(struct item *item)
@@ -313,23 +342,31 @@ static int append_pending_list(struct item *item)
                        return LB_STATUS_ERROR_EXIST;
                }
 
-               if (activate_pending_consumer() < 0)
+               if (activate_pending_consumer() < 0) {
                        return LB_STATUS_ERROR_FAULT;
+               }
 
                s_info.pending_list = eina_list_append(s_info.pending_list, item);
        }
        return 0;
 }
 
-static inline void timer_thaw(struct item *item)
+/*!
+ * \brief
+ *   This function can call the update callback
+ * return 0 if there is no changes
+ * return -1 the item is deleted
+ */
+static inline int timer_thaw(struct item *item)
 {
        double pending;
        double period;
        double delay;
        double sleep_time;
 
-       if (!item->timer)
-               return;
+       if (!item->timer) {
+               return 0;
+       }
 
        ecore_timer_thaw(item->timer);
        period = ecore_timer_interval_get(item->timer);
@@ -337,28 +374,41 @@ static inline void timer_thaw(struct item *item)
        delay = util_time_delay_for_compensation(period) - pending;
        ecore_timer_delay(item->timer, delay);
 
-       if (item->sleep_at == 0.0f)
-               return;
+       if (item->sleep_at == 0.0f) {
+               return 0;
+       }
 
        sleep_time = util_timestamp() - item->sleep_at;
-       if (sleep_time > pending)
-               (void)updator_cb(item);
-
        item->sleep_at = 0.0f;
+
+       if (sleep_time > pending) {
+               if (updator_cb(item) == ECORE_CALLBACK_CANCEL) {
+                       /* item is destroyed */
+                       return UPDATE_ITEM_DELETED;
+               } else {
+                       return UPDATE_INVOKED;
+               }
+       }
+
+       return UPDATE_NOT_INVOKED;
 }
 
-static inline void timer_freeze(struct item *item)
+static void timer_freeze(struct item *item)
 {
-       struct timeval tv;
-
-       if (!item->timer)
+       if (!item->timer) {
                return;
+       }
 
        ecore_timer_freeze(item->timer);
 
-       if (ecore_timer_interval_get(item->timer) <= 1.0f)
+       if (ecore_timer_interval_get(item->timer) <= 1.0f) {
                return;
+       }
 
+#if defined(_USE_ECORE_TIME_GET)
+       item->sleep_at = ecore_time_get();
+#else
+       struct timeval tv;
        if (gettimeofday(&tv, NULL) < 0) {
                ErrPrint("gettimeofday: %s\n", strerror(errno));
                tv.tv_sec = 0;
@@ -366,6 +416,7 @@ static inline void timer_freeze(struct item *item)
        }
 
        item->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+#endif
 }
 
 static inline void update_monitor_cnt(struct item *item)
@@ -385,7 +436,7 @@ static inline void update_monitor_cnt(struct item *item)
         * file update callback.
         */
        if (interval >= MINIMUM_UPDATE_INTERVAL) {
-               if (s_info.update == item) {
+               if (eina_list_data_find(s_info.update_list, item)) {
                        /*!
                         * \note
                         * If already in updating mode,
@@ -410,8 +461,9 @@ static inline Eina_List *find_item(struct instance *inst)
        struct item *item;
        
        EINA_LIST_FOREACH(s_info.item_list, l, item) {
-               if (item->inst == inst)
+               if (item->inst == inst) {
                        return l;
+               }
        }
 
        return NULL;
@@ -434,16 +486,16 @@ static inline int output_handler(struct item *item)
        }
 
        if (item->monitor_cnt == 0) {
-               if (!invalid)
+               if (!invalid) {
                        fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
+               }
 
                if (item->monitor) {
                        ecore_timer_del(item->monitor);
                        item->monitor = NULL;
                }
 
-               if (s_info.update == item)
-                       s_info.update = NULL;
+               s_info.update_list = eina_list_remove(s_info.update_list, item);
 
                if (item->deleteme) {
                        provider_send_deleted(item->inst->item->pkgname, item->inst->id);
@@ -460,8 +512,9 @@ static int desc_updated_cb(const char *filename, void *data, int over)
 {
        struct item *item;
 
-       if (over)
+       if (over) {
                WarnPrint("Event Q overflow\n");
+       }
 
        item = data;
 
@@ -484,8 +537,9 @@ static int file_updated_cb(const char *filename, void *data, int over)
        char *title = NULL;
        int ret;
 
-       if (over)
+       if (over) {
                WarnPrint("Event Q overflow\n");
+       }
 
        item = data;
 
@@ -514,8 +568,9 @@ static int file_updated_cb(const char *filename, void *data, int over)
 
 static void reset_lb_updated_flag(struct item *item)
 {
-       if (!item->is_lb_updated)
+       if (!item->is_lb_updated) {
                return;
+       }
 
        DbgPrint("[%s] Updated %d times, (content: %s), (title: %s)\n",
                        item->inst->id, item->is_lb_updated,
@@ -534,12 +589,14 @@ static inline int clear_from_pd_open_pending_list(struct item *item)
        struct item *tmp;
 
        EINA_LIST_FOREACH(s_info.pd_open_pending_list, l, tmp) {
-               if (tmp != item)
+               if (tmp != item) {
                        continue;
+               }
 
                s_info.pd_open_pending_list = eina_list_remove_list(s_info.pd_open_pending_list, l);
-               if (!s_info.pd_open_pending_list)
+               if (!s_info.pd_open_pending_list) {
                        deactivate_pd_open_pending_consumer();
+               }
                return LB_STATUS_SUCCESS;
        }
 
@@ -552,12 +609,14 @@ static inline int clear_from_pending_list(struct item *item)
        struct item *tmp;
 
        EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
-               if (tmp != item)
+               if (tmp != item) {
                        continue;
+               }
 
                s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
-               if (!s_info.pending_list)
+               if (!s_info.pending_list) {
                        deactivate_pending_consumer();
+               }
                return LB_STATUS_SUCCESS;
        }
 
@@ -572,17 +631,23 @@ static Eina_Bool update_timeout_cb(void *data)
 
        ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
 
-       if (s_info.update != item)
+       if (!eina_list_data_find(s_info.update_list, item)) {
                ErrPrint("Updating item is not matched\n");
+       }
 
        fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
        fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
-       s_info.update = NULL;
+       s_info.update_list = eina_list_remove(s_info.update_list, item);
 
        exit(ETIME);
        return ECORE_CALLBACK_CANCEL;
 }
 
+/*!
+ * \note
+ * This must has to return ECORE_CALLBACK_CANCEL, only if the item is deleted.
+ * So every caller, should manage the deleted item correctly.
+ */
 static Eina_Bool updator_cb(void *data)
 {
        struct item *item;
@@ -590,7 +655,7 @@ static Eina_Bool updator_cb(void *data)
 
        item = data;
 
-       if (item->monitor) {/*!< If this item is already in update process */
+       if (item->monitor) { /*!< If this item is already in update process */
                return ECORE_CALLBACK_RENEW;
        }
 
@@ -613,6 +678,10 @@ static Eina_Bool updator_cb(void *data)
                if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
                        provider_send_deleted(item->inst->item->pkgname, item->inst->id);
                        lb_destroy(item->inst->item->pkgname, item->inst->id);
+                       /*!
+                        * \CRITICAL
+                        * Every caller of this, must not access the item from now.
+                        */
                        return ECORE_CALLBACK_CANCEL;
                }
 
@@ -620,8 +689,12 @@ static Eina_Bool updator_cb(void *data)
                return ECORE_CALLBACK_RENEW;
        }
 
-       if (s_info.update || pd_is_opened(item->inst->item->pkgname) < 0) {
-               DbgPrint("%s is busy\n", s_info.update ? s_info.update->inst->id : item->inst->id);
+       /*!
+        * \note
+        * Check the update_list, if you want make serialized update
+        */
+       if (/*s_info.update_list || */pd_is_opened(item->inst->item->pkgname) < 0) {
+               DbgPrint("%s is busy\n", item->inst->id);
                (void)append_pending_list(item);
                return ECORE_CALLBACK_RENEW;
        }
@@ -656,8 +729,9 @@ static Eina_Bool updator_cb(void *data)
         */
        fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
 
-       if (ret & NEED_TO_SCHEDULE)
+       if (ret & NEED_TO_SCHEDULE) {
                (void)append_pending_list(item);
+       }
 
        if (ret & OUTPUT_UPDATED) {
                /*!
@@ -676,7 +750,7 @@ static Eina_Bool updator_cb(void *data)
         * This should be updated after "update_monitor_cnt" function call,
         * because the update_monitor_cnt function will see the s_info.update variable,
         */
-       s_info.update = item;
+       s_info.update_list = eina_list_append(s_info.update_list, item);
 
        return ECORE_CALLBACK_RENEW;
 }
@@ -704,6 +778,7 @@ static inline int add_desc_update_monitor(const char *id, struct item *item)
 {
        char *filename;
        int len;
+       int ret;
 
        len = strlen(util_uri_to_path(id)) + strlen(".desc") + 1;
        filename = malloc(len);
@@ -713,20 +788,14 @@ static inline int add_desc_update_monitor(const char *id, struct item *item)
        }
 
        snprintf(filename, len, "%s.desc", util_uri_to_path(id));
-       return update_monitor_add_update_cb(filename, desc_updated_cb, item);
+       ret = update_monitor_add_update_cb(filename, desc_updated_cb, item);
+       free(filename);
+       return ret;
 }
 
 static inline int add_file_update_monitor(const char *id, struct item *item)
 {
-       char *filename;
-
-       filename = strdup(util_uri_to_path(id));
-       if (!filename) {
-               ErrPrint("Heap: %s (%s)\n", strerror(errno), id);
-               return LB_STATUS_ERROR_MEMORY;
-       }
-
-       return update_monitor_add_update_cb(filename, file_updated_cb, item);
+       return update_monitor_add_update_cb(util_uri_to_path(id), file_updated_cb, item);
 }
 
 static inline int update_monitor_add(const char *id, struct item *item)
@@ -775,8 +844,9 @@ const char *livebox_find_pkgname(const char *filename)
        struct item *item;
 
        EINA_LIST_FOREACH(s_info.item_list, l, item) {
-               if (!strcmp(item->inst->id, filename))
+               if (!strcmp(item->inst->id, filename)) {
                        return item->inst->item->pkgname;
+               }
        }
 
        return NULL;
@@ -789,7 +859,14 @@ int livebox_request_update_by_id(const char *filename)
 
        if (so_current_op() != LIVEBOX_OP_UNKNOWN) {
                ErrPrint("Current operation: %d\n", so_current_op());
-               return LB_STATUS_ERROR_INVALID;
+               /*!
+                * \note
+                * Some case requires to update the content of other box from livebox_XXX ABI.
+                * In that case this function can be used so we have not to filter it from here.
+                * ex) Setting accessibility.
+                * Press the assistive light, turned on, need to update other instances too.
+                * Then the box will use this function from livebox_clicked function.
+                */
        }
 
        EINA_LIST_FOREACH(s_info.item_list, l, item) {
@@ -847,8 +924,9 @@ HAPI int lb_open_pd(const char *pkgname)
        char *tmp;
 
        EINA_LIST_FOREACH(s_info.pd_list, l, tmp) {
-               if (!strcmp(pkgname, tmp))
+               if (!strcmp(pkgname, tmp)) {
                        return 0;
+               }
        }
 
        tmp = strdup(pkgname);
@@ -857,8 +935,9 @@ HAPI int lb_open_pd(const char *pkgname)
                return LB_STATUS_ERROR_MEMORY;
        }
 
-       if (!s_info.pd_list)
+       if (!s_info.pd_list) {
                pending_timer_freeze();
+       }
 
        s_info.pd_list = eina_list_append(s_info.pd_list, tmp);
 
@@ -877,14 +956,16 @@ HAPI int lb_close_pd(const char *pkgname)
        char *tmp;
 
        EINA_LIST_FOREACH_SAFE(s_info.pd_list, l, n, tmp) {
-               if (strcmp(tmp, pkgname))
+               if (strcmp(tmp, pkgname)) {
                        continue;
+               }
 
                s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
                free(tmp);
 
-               if (!s_info.pd_list)
+               if (!s_info.pd_list) {
                        pending_timer_thaw();
+               }
 
                /*!
                 * Move all items in pd_open_pending_list
@@ -917,8 +998,9 @@ HAPI int lb_create(const char *pkgname, const char *id, const char *content_info
 
        if (!skip_need_to_create) {
                ret = so_create_needed(pkgname, cluster, category, abi);
-               if (ret != NEED_TO_CREATE)
+               if (ret != NEED_TO_CREATE) {
                        return LB_STATUS_ERROR_PERMISSION;
+               }
 
                need_to_create = 1;
        }
@@ -958,8 +1040,9 @@ HAPI int lb_create(const char *pkgname, const char *id, const char *content_info
                        return LB_STATUS_ERROR_FAULT;
                }
 
-               if (s_info.paused)
+               if (s_info.paused) {
                        timer_freeze(item);
+               }
        } else {
                DbgPrint("Local update timer is disabled: %lf (%d)\n", period, s_info.secured);
                item->timer = NULL;
@@ -988,8 +1071,9 @@ HAPI int lb_create(const char *pkgname, const char *id, const char *content_info
                                char *tmp;
 
                                tmp = strdup(*out_content);
-                               if (!tmp)
+                               if (!tmp) {
                                        ErrPrint("Memory: %s\n", strerror(errno));
+                               }
 
                                *out_content = tmp;
                        }
@@ -998,8 +1082,9 @@ HAPI int lb_create(const char *pkgname, const char *id, const char *content_info
                                char *tmp;
 
                                tmp = strdup(*out_title);
-                               if (!tmp)
+                               if (!tmp) {
                                        ErrPrint("Memory: %s\n", strerror(errno));
+                               }
 
                                *out_title = tmp;
                        }
@@ -1033,8 +1118,7 @@ HAPI int lb_destroy(const char *pkgname, const char *id)
        item = eina_list_data_get(l);
        s_info.item_list = eina_list_remove_list(s_info.item_list, l);
 
-       if (s_info.update == item)
-               s_info.update = NULL;
+       s_info.update_list = eina_list_remove(s_info.update_list, item);
 
        if (item->timer) {
                clear_from_pd_open_pending_list(item);
@@ -1042,10 +1126,11 @@ HAPI int lb_destroy(const char *pkgname, const char *id)
                ecore_timer_del(item->timer);
                item->timer = NULL;
 
-               if (item->monitor)
+               if (item->monitor) {
                        item->deleteme = 1;
-               else
+               } else {
                        update_monitor_del(id, item);
+               }
        }
 
        if (!item->monitor) {
@@ -1078,16 +1163,18 @@ HAPI int lb_resize(const char *pkgname, const char *id, int w, int h)
        item = eina_list_data_get(l);
 
        ret = so_resize(inst, w, h);
-       if (ret < 0)
+       if (ret < 0) {
                return ret;
+       }
 
        if (ret & NEED_TO_SCHEDULE) {
                DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
                (void)append_pending_list(item);
        }
 
-       if (ret & OUTPUT_UPDATED)
+       if (ret & OUTPUT_UPDATED) {
                update_monitor_cnt(item);
+       }
 
        return LB_STATUS_SUCCESS;
 }
@@ -1142,8 +1229,9 @@ HAPI int lb_set_period(const char *pkgname, const char *id, double period)
                                return LB_STATUS_ERROR_FAULT;
                        }
 
-                       if (s_info.paused)
+                       if (s_info.paused) {
                                timer_freeze(item);
+                       }
                }
        }
 
@@ -1172,16 +1260,18 @@ HAPI int lb_clicked(const char *pkgname, const char *id, const char *event, doub
        item = eina_list_data_get(l);
 
        ret = so_clicked(inst, event, timestamp, x, y);
-       if (ret < 0)
+       if (ret < 0) {
                return ret;
+       }
 
        if (ret & NEED_TO_SCHEDULE) {
                DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
                (void)append_pending_list(item);
        }
 
-       if (ret & OUTPUT_UPDATED)
+       if (ret & OUTPUT_UPDATED) {
                update_monitor_cnt(item);
+       }
 
        return LB_STATUS_SUCCESS;
 }
@@ -1212,8 +1302,9 @@ HAPI int lb_script_event(const char *pkgname, const char *id, const char *emissi
                        if (!strcmp(emission, "lb,show")) {
                                item->is_lb_show = 1;
 
-                               if (item->is_lb_updated && !is_pended_item(item))
+                               if (item->is_lb_updated && !is_pended_item(item)) {
                                        reset_lb_updated_flag(item);
+                               }
 
                                source = util_uri_to_path(source);
                        } else if (!strcmp(emission, "lb,hide")) {
@@ -1234,16 +1325,18 @@ HAPI int lb_script_event(const char *pkgname, const char *id, const char *emissi
        }
 
        ret = so_script_event(inst, emission, source, event_info);
-       if (ret < 0)
+       if (ret < 0) {
                return ret;
+       }
 
        if (ret & NEED_TO_SCHEDULE) {
                DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
                (void)append_pending_list(item);
        }
 
-       if (ret & OUTPUT_UPDATED)
+       if (ret & OUTPUT_UPDATED) {
                update_monitor_cnt(item);
+       }
 
        return LB_STATUS_SUCCESS;
 }
@@ -1301,33 +1394,38 @@ HAPI int lb_change_group(const char *pkgname, const char *id, const char *cluste
        item = eina_list_data_get(l);
 
        ret = so_change_group(inst, cluster, category);
-       if (ret < 0)
+       if (ret < 0) {
                return ret;
+       }
 
        if (ret & NEED_TO_SCHEDULE) {
                DbgPrint("%s Returns NEED_TO_SCHEDULE\n", pkgname);
                (void)append_pending_list(item);
        }
 
-       if (ret & OUTPUT_UPDATED)
+       if (ret & OUTPUT_UPDATED) {
                update_monitor_cnt(item);
+       }
 
        return LB_STATUS_SUCCESS;
 }
 
-static inline int lb_sys_event(struct instance *inst, struct item *item, int event)
+static int lb_sys_event(struct instance *inst, struct item *item, int event)
 {
        int ret;
 
        ret = so_sys_event(inst, event);
-       if (ret < 0)
+       if (ret < 0) {
                return ret;
+       }
 
-       if (ret & NEED_TO_SCHEDULE)
+       if (ret & NEED_TO_SCHEDULE) {
                (void)append_pending_list(item);
+       }
 
-       if (ret & OUTPUT_UPDATED)
+       if (ret & OUTPUT_UPDATED) {
                update_monitor_cnt(item);
+       }
 
        return LB_STATUS_SUCCESS;
 }
@@ -1385,14 +1483,17 @@ HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *cat
 
        DbgPrint("Update content for %s\n", pkgname ? pkgname : "(all)");
        EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
-               if (item->deleteme)
+               if (item->deleteme) {
                        continue;
+               }
 
-               if (cluster && strcasecmp(item->inst->cluster, cluster))
+               if (cluster && strcasecmp(item->inst->cluster, cluster)) {
                        continue;
+               }
 
-               if (category && strcasecmp(item->inst->category, category))
+               if (category && strcasecmp(item->inst->category, category)) {
                        continue;
+               }
 
                if (pkgname && strlen(pkgname)) {
                        if (!strcmp(item->inst->item->pkgname, pkgname)) {
@@ -1414,10 +1515,9 @@ HAPI int lb_delete_all_deleteme(void)
        int cnt = 0;
 
        EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
-               if (!item->deleteme)
+               if (!item->deleteme) {
                        continue;
-
-               s_info.item_list = eina_list_remove(s_info.item_list, item);
+               }
 
                update_monitor_del(item->inst->id, item);
                (void)so_destroy(item->inst);
@@ -1436,8 +1536,9 @@ HAPI int lb_system_event_all(int event)
        struct item *item;
 
        EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
-               if (item->deleteme)
+               if (item->deleteme) {
                        continue;
+               }
 
                DbgPrint("System event for %s (%d)\n", item->inst->id, event);
                lb_sys_event(item->inst, item, event);
@@ -1461,8 +1562,9 @@ HAPI void lb_pause_all(void)
                        continue;
                }
 
-               if (item->is_paused)
+               if (item->is_paused) {
                        continue;
+               }
 
                timer_freeze(item);
 
@@ -1473,22 +1575,22 @@ HAPI void lb_pause_all(void)
 HAPI void lb_resume_all(void)
 {
        Eina_List *l;
+       Eina_List *n;
        struct item *item;
 
        s_info.paused = 0;
 
        pending_timer_thaw();
 
-       EINA_LIST_FOREACH(s_info.item_list, l, item) {
+       EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
                if (item->deleteme) {
                        DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);
                        continue;
                }
 
-               if (item->is_paused)
+               if (item->is_paused) {
                        continue;
-
-               timer_thaw(item);
+               }
 
                lb_sys_event(item->inst, item, LB_SYS_EVENT_RESUMED);
 
@@ -1496,6 +1598,17 @@ HAPI void lb_resume_all(void)
                        (void)append_pending_list(item);
                        item->updated_in_pause = 0;
                }
+
+               /*!
+                * \note
+                * After send the resume callback, call this function.
+                * Because the timer_thaw can call the update function.
+                * Before resumed event is notified to the livebox,
+                * Do not call update function
+                */
+               if (timer_thaw(item) == UPDATE_ITEM_DELETED) {
+                       /* item is deleted */
+               }
        }
 }
 
@@ -1506,8 +1619,9 @@ HAPI int lb_pause(const char *pkgname, const char *id)
        struct item *item;
 
        inst = so_find_instance(pkgname, id);
-       if (!inst)
+       if (!inst) {
                return LB_STATUS_ERROR_INVALID;
+       }
 
        l = find_item(inst);
        if (!l) {
@@ -1516,8 +1630,9 @@ HAPI int lb_pause(const char *pkgname, const char *id)
        }
 
        item = eina_list_data_get(l);
-       if (!item)
+       if (!item) {
                return LB_STATUS_ERROR_FAULT;
+       }
 
        if (item->deleteme) {
                DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
@@ -1526,8 +1641,9 @@ HAPI int lb_pause(const char *pkgname, const char *id)
 
        item->is_paused = 1;
 
-       if (s_info.paused)
+       if (s_info.paused) {
                return LB_STATUS_SUCCESS;
+       }
 
        timer_freeze(item);
 
@@ -1541,10 +1657,12 @@ HAPI int lb_resume(const char *pkgname, const char *id)
        struct instance *inst;
        Eina_List *l;
        struct item *item;
+       int ret;
 
        inst = so_find_instance(pkgname, id);
-       if (!inst)
+       if (!inst) {
                return LB_STATUS_ERROR_INVALID;
+       }
 
        l = find_item(inst);
        if (!l) {
@@ -1553,8 +1671,9 @@ HAPI int lb_resume(const char *pkgname, const char *id)
        }
 
        item = eina_list_data_get(l);
-       if (!item)
+       if (!item) {
                return LB_STATUS_ERROR_FAULT;
+       }
 
        if (item->deleteme) {
                DbgPrint("Instance %s will be deleted (%s)\n", item->inst->item->pkgname, item->inst->id);
@@ -1563,13 +1682,27 @@ HAPI int lb_resume(const char *pkgname, const char *id)
 
        item->is_paused = 0;
 
-       if (s_info.paused)
+       if (s_info.paused) {
                return LB_STATUS_SUCCESS;
-
-       timer_thaw(item);
+       }
 
        lb_sys_event(inst, item, LB_SYS_EVENT_RESUMED);
 
+       ret = timer_thaw(item);
+       if (ret == UPDATE_ITEM_DELETED) {
+               /*!
+                * \note
+                * ITEM is deleted
+                */
+               return LB_STATUS_SUCCESS;
+       } else if (ret == UPDATE_INVOKED) {
+               /*!
+                * \note
+                * if the update is successfully done, the updated_in_pause will be reset'd.
+                * or append it to the pending list
+                */
+       }
+
        if (item->updated_in_pause) {
                (void)append_pending_list(item);
                item->updated_in_pause = 0;