From 31c28d61620c7fb0e43b683cb58aa031e05e4e9d Mon Sep 17 00:00:00 2001 From: Jiwoong Im Date: Wed, 13 Jul 2016 14:38:33 +0900 Subject: [PATCH] vconf-compat : modify calling noti callback in idler - There is a timing issue that noti callback is called after unregistered To fix this issue, find noti callback in idler and call the noti callback Change-Id: I1299da587bf6f99c3e4955f758e4149306dc0b54 Signed-off-by: Jiwoong Im --- vconf-compat/vconf.c | 91 +++++++++++++++++----------------------------------- 1 file changed, 30 insertions(+), 61 deletions(-) diff --git a/vconf-compat/vconf.c b/vconf-compat/vconf.c index fb16060..10d4173 100644 --- a/vconf-compat/vconf.c +++ b/vconf-compat/vconf.c @@ -42,7 +42,6 @@ static struct buxton_client *noti_client; static struct buxton_layer *system_layer; static struct buxton_layer *memory_layer; static GHashTable *noti_tbl; -static GAsyncQueue *cbs_queue; struct noti { char *key; @@ -55,12 +54,6 @@ struct noti_cb { int ref_cnt; }; -struct cbs_queue_item { - keynode_t *node; - vconf_callback_fn cb; - void *user_data; -}; - static bool last_result; static void free_keynode(struct _keynode_t *keynode) @@ -185,12 +178,6 @@ static void free_noti(struct noti *noti) free(noti); } -static void free_cbs(struct cbs_queue_item *item) -{ - free_keynode(item->node); - free(item); -} - static void _close_for_noti(void) { pthread_mutex_lock(&vconf_lock); @@ -210,8 +197,6 @@ static void _close_for_noti(void) g_hash_table_destroy(noti_tbl); noti_tbl = NULL; - g_async_queue_unref(cbs_queue); - buxton_close(noti_client); noti_client = NULL; @@ -243,8 +228,6 @@ static int _open_for_noti(void) system_layer = buxton_create_layer("system"); memory_layer = buxton_create_layer("memory"); - cbs_queue = g_async_queue_new_full((GDestroyNotify)free_cbs); - pthread_mutex_unlock(&vconf_lock); return 0; } @@ -376,62 +359,48 @@ static GList *free_copy_list(GList *noti_list, GList *copy_list) static gboolean call_noti_cb(gpointer data) { - struct cbs_queue_item *item; - - g_async_queue_lock(cbs_queue); - item = g_async_queue_try_pop_unlocked(cbs_queue); - while (item) { - g_async_queue_unlock(cbs_queue); - item->cb(item->node, item->user_data); - g_async_queue_lock(cbs_queue); - free_cbs(item); - item = g_async_queue_try_pop_unlocked(cbs_queue); - } - g_async_queue_unlock(cbs_queue); - - return G_SOURCE_REMOVE; -} - -static void notify_cb(const struct buxton_layer *layer, const char *key, - const struct buxton_value *val, void *user_data) -{ - struct noti *noti = user_data; + keynode_t *node = (keynode_t *)data; + struct noti *noti; GList *l; GList *copy; - assert(noti); + pthread_mutex_lock(&vconf_lock); + noti = g_hash_table_lookup(noti_tbl, node->keyname); + if (!noti) { + pthread_mutex_unlock(&vconf_lock); + return G_SOURCE_REMOVE; + } + pthread_mutex_unlock(&vconf_lock); + copy = copy_noti_list(noti->noti_list); - g_async_queue_lock(cbs_queue); for (l = copy; l; l = g_list_next(l)) { struct noti_cb *noticb = l->data; - struct cbs_queue_item *item; - keynode_t *node; - - item = calloc(1, sizeof(*item)); - if (!item) - continue; - node = calloc(1, sizeof(*node)); - if (!node) { - free(item); - continue; - } - - node->keyname = strdup(key); - to_vconf_t(val, node); - - item->node = node; - item->cb = noticb->cb; - item->user_data = noticb->user_data; assert(noticb->cb); - g_async_queue_push_unlocked(cbs_queue, item); + noticb->cb(node, noticb->user_data); } - g_async_queue_unlock(cbs_queue); noti->noti_list = free_copy_list(noti->noti_list, copy); - g_idle_add(call_noti_cb, NULL); + free_keynode(node); + + return G_SOURCE_REMOVE; +} + +static void notify_cb(const struct buxton_layer *layer, const char *key, + const struct buxton_value *val, void *user_data) +{ + keynode_t *node; + + node = calloc(1, sizeof(*node)); + if (!node) + return; + + node->keyname = strdup(key); + to_vconf_t(val, node); + + g_idle_add(call_noti_cb, node); } static struct noti_cb *find_noti_cb(struct noti *noti, vconf_callback_fn cb) @@ -535,7 +504,7 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb, return -1; } r = buxton_register_notification_sync(noti_client, get_layer(key), key, - notify_cb, noti); + notify_cb, NULL); if (r == -1) { LOGE("vconf_notify_key_changed: key '%s' add notify error %d", key, errno); -- 2.7.4