#define LOG_TAG "VCONF"
static void _restore_noti_cb(gpointer key, gpointer value, gpointer user_data);
+static void _close(void);
static pthread_mutex_t vconf_lock = PTHREAD_MUTEX_INITIALIZER;
static int _refcnt;
static struct buxton_layer *system_layer;
static struct buxton_layer *memory_layer;
static GHashTable *noti_tbl;
+static GHashTable *gsource_tbl;
struct noti {
char *key;
bool in_cb;
};
+struct callback_info {
+ keynode_t *key_node;
+ int source_id; /**< GSource id for call_noti_cb*/
+};
+
static bool last_result;
static void free_keynode(struct _keynode_t *keynode)
free(keynode);
}
+static void free_callback_info(struct callback_info *cb_info)
+{
+ if (!cb_info)
+ return;
+
+ free_keynode(cb_info->key_node);
+ g_source_remove(cb_info->source_id);
+ free(cb_info);
+}
+
+__attribute__((destructor))
+static void _vconf_finish(void)
+{
+ /* force close */
+ if (_refcnt > 0) {
+ _refcnt = 1;
+ _close();
+ }
+
+ if (gsource_tbl)
+ g_hash_table_remove_all(gsource_tbl);
+}
EXPORT char *vconf_keynode_get_name(keynode_t *keynode)
{
static gboolean call_noti_cb(gpointer data)
{
- keynode_t *node = (keynode_t *)data;
+ struct callback_info *cb_info = (struct callback_info *)data;
+ keynode_t *node = cb_info->key_node;
struct noti *noti;
GList *l;
GList *copy;
noti->noti_list = free_copy_list(noti->noti_list, copy);
- free_keynode(node);
+ g_hash_table_remove(gsource_tbl, GINT_TO_POINTER(cb_info->source_id));
return G_SOURCE_REMOVE;
}
const struct buxton_value *val, void *user_data)
{
keynode_t *node;
+ struct callback_info *cb_info;
node = calloc(1, sizeof(*node));
- if (!node)
+ if (!node) {
+ LOGE("Failed to create keynode_t");
return;
+ }
node->keyname = strdup(key);
to_vconf_t(val, node);
- g_idle_add_full(G_PRIORITY_HIGH, call_noti_cb, node, NULL);
+ cb_info = calloc(1, sizeof(*cb_info));
+ if (!cb_info) {
+ free_keynode(node);
+ LOGE("Failed to create callback_info_s");
+ return;
+ }
+
+ cb_info->key_node = node;
+ cb_info->source_id = g_idle_add_full(G_PRIORITY_HIGH, call_noti_cb, cb_info, NULL);
+
+ if (gsource_tbl == NULL)
+ gsource_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify)free_callback_info);
+
+ g_hash_table_insert(gsource_tbl, GINT_TO_POINTER(cb_info->source_id), cb_info);
}
static struct noti_cb *find_noti_cb(struct noti *noti, vconf_callback_fn cb)