From 470bee83fd1039a370745be4eadfaa8f53abb2ac Mon Sep 17 00:00:00 2001 From: Jiwoong Im Date: Wed, 25 Jan 2017 13:33:56 +0900 Subject: [PATCH] Restore applying cache in vconf library side - Cache is only used if client uses g_main_loop. Change-Id: I7096602f921af78e0547b86678e3a1fc962a3d24 Signed-off-by: Jiwoong Im --- vconf-compat/vconf.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/vconf-compat/vconf.c b/vconf-compat/vconf.c index cc793b0..e404c2c 100644 --- a/vconf-compat/vconf.c +++ b/vconf-compat/vconf.c @@ -41,6 +41,8 @@ #define LOG_TAG "VCONF" +#define HASH_SIZE 10 + static void _restore_noti_cb(gpointer key, gpointer value, gpointer user_data); static pthread_mutex_t vconf_lock = PTHREAD_MUTEX_INITIALIZER; @@ -49,6 +51,8 @@ static struct buxton_client *client; static struct buxton_layer *system_layer; static struct buxton_layer *memory_layer; static GHashTable *noti_tbl; +static GHashTable *cache_tbl; +static GQueue *victims; struct noti { char *key; @@ -62,6 +66,8 @@ struct noti_cb { }; static bool last_result; +static bool cache_enable; +static bool cache_check_done; static void free_keynode(struct _keynode_t *keynode) { @@ -201,6 +207,16 @@ static void _close(void) g_hash_table_destroy(noti_tbl); noti_tbl = NULL; + if (cache_tbl) { + g_hash_table_destroy(cache_tbl); + cache_tbl = NULL; + } + + if (victims) { + g_queue_free_full(victims, (GDestroyNotify)free); + victims = NULL; + } + buxton_close(client); client = NULL; } @@ -232,6 +248,12 @@ static void _restore_connection(enum buxton_status status, pthread_mutex_unlock(&vconf_lock); } +static gboolean _enable_cache(gpointer data) +{ + cache_enable = true; + return G_SOURCE_REMOVE; +} + static int _open(void) { int r; @@ -260,6 +282,22 @@ static int _open(void) if (!memory_layer) memory_layer = buxton_create_layer("memory"); + if (!cache_tbl) { + cache_tbl = g_hash_table_new_full(g_str_hash, g_str_equal, + (GDestroyNotify)free, + (GDestroyNotify)buxton_value_free); + } + + if (!victims) { + victims = g_queue_new(); + g_queue_init(victims); + } + + if (!cache_check_done) { + g_idle_add(_enable_cache, NULL); + cache_check_done = true; + } + return 0; } @@ -638,8 +676,17 @@ static int _vconf_set(const char *key, const struct buxton_value *val) } r = buxton_set_value_sync(client, get_layer(key), key, val); - if (r == -1) + if (r == -1) { LOGE("set value: key '%s' errno %d", key, errno); + } else { + if (cache_enable) { + if (g_hash_table_contains(cache_tbl, key)) { + g_hash_table_replace(cache_tbl, + strdup(key), + buxton_value_duplicate(val)); + } + } + } _close(); pthread_mutex_unlock(&vconf_lock); @@ -743,22 +790,89 @@ EXPORT int vconf_set_dbl(const char *key, double dblval) return r; } +static void _cache_cb(const struct buxton_layer *layer, const char *key, + const struct buxton_value *val, void *user_data) +{ + if (g_hash_table_contains(cache_tbl, key)) { + g_hash_table_replace(cache_tbl, + strdup(key), buxton_value_duplicate(val)); + } +} + + +static void _reduce_cache() +{ + char *key; + int r; + + key = (char *)g_queue_pop_tail(victims); + if (key == NULL) + return; + + r = g_hash_table_remove(cache_tbl, key); + if (r == false) + return; + + r = buxton_unregister_notification_sync(client, get_layer(key), + key, _cache_cb); + if (r == -1) + return; + + _close(); + + free(key); +} + +static void _insert_cache(const char *key, struct buxton_value *val) +{ + int r; + + r = _open(); + if (r == -1) + return; + + if (g_hash_table_size(cache_tbl) >= HASH_SIZE) + _reduce_cache(); + + r = buxton_register_notification_sync(client, get_layer(key), key, + _cache_cb, NULL); + + if (r == -1) { + _close(); + return; + } + + g_queue_push_head(victims, (char *)strdup(key)); + r = g_hash_table_insert(cache_tbl, strdup(key), + buxton_value_duplicate(val)); +} + static int _vconf_get(const char *key, enum buxton_key_type type, struct buxton_value **val) { int r; - struct buxton_value *v; + struct buxton_value *v = NULL; assert(key); assert(val); pthread_mutex_lock(&vconf_lock); + r = _open(); if (r == -1) { pthread_mutex_unlock(&vconf_lock); return -1; } + if (cache_enable) + v = g_hash_table_lookup(cache_tbl, key); + if (v) { + *val = buxton_value_duplicate(v); + _close(); + pthread_mutex_unlock(&vconf_lock); + return 0; + } + r = buxton_get_value_sync(client, get_layer(key), key, &v); if (r == -1) { LOGE("get value: key '%s' errno %d", key, errno); @@ -776,9 +890,12 @@ static int _vconf_get(const char *key, enum buxton_key_type type, } else { *val = v; } + if (cache_enable) + _insert_cache(key, v); } _close(); + pthread_mutex_unlock(&vconf_lock); return r; -- 2.7.4