diff options
author | Hwankyu Jhun <h.jhun@samsung.com> | 2022-03-04 10:48:26 +0900 |
---|---|---|
committer | Hwankyu Jhun <h.jhun@samsung.com> | 2022-03-04 10:58:09 +0900 |
commit | 7719266b0b54ff15f3cea514c86c4f1e8a09db32 (patch) | |
tree | 5b016291a909cffe1a232f5fa50ffb9ab302f313 | |
parent | b20fde67c2a272734dcfeb6486acefea89aca7ca (diff) | |
download | buxton2-7719266b0b54ff15f3cea514c86c4f1e8a09db32.tar.gz buxton2-7719266b0b54ff15f3cea514c86c4f1e8a09db32.tar.bz2 buxton2-7719266b0b54ff15f3cea514c86c4f1e8a09db32.zip |
Use recursive mutex
To avoid deadlock state, vconf API uses recursive mutex.
Change-Id: I30bf03f40d2c8f06cd5499926bc988015bec20fe
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
-rw-r--r-- | vconf-compat/vconf.c | 122 |
1 files changed, 72 insertions, 50 deletions
diff --git a/vconf-compat/vconf.c b/vconf-compat/vconf.c index f81a762..2f7ca9c 100644 --- a/vconf-compat/vconf.c +++ b/vconf-compat/vconf.c @@ -52,11 +52,14 @@ static int last_errno; last_result = false; \ } while (0) +#define VCONF_CTOR __attribute__((constructor)) +#define VCONF_DTOR __attribute__((destructor)) + static void _vconf_restore_noti_cb(gpointer key, gpointer value, gpointer user_data); static void _vconf_con_close(void); static gboolean _vconf_call_noti_cb(gpointer data); -static pthread_mutex_t vconf_lock = PTHREAD_MUTEX_INITIALIZER; +static GRecMutex vconf_mutex; static int _refcnt; static struct buxton_client *client; static struct buxton_layer *system_layer; @@ -87,6 +90,16 @@ struct callback_info { static struct noti_cb *_vconf_find_noti_cb(struct noti *noti, vconf_callback_fn cb); static void _vconf_to_vconf_t(const struct buxton_value *val, keynode_t *node); +static void _vconf_mutex_lock(void) +{ + g_rec_mutex_lock(&vconf_mutex); +} + +static void _vconf_mutex_unlock(void) +{ + g_rec_mutex_unlock(&vconf_mutex); +} + static GSource *_vconf_idle_add_full(GMainContext *context, guint priority, GSourceFunc func, gpointer data) { @@ -210,8 +223,12 @@ static struct callback_info *_vconf_create_callback_info(const char *key, return cb_info; } -__attribute__((destructor)) -static void _vconf_finish(void) +VCONF_CTOR static void _vconf_init(void) +{ + g_rec_mutex_init(&vconf_mutex); +} + +VCONF_DTOR static void _vconf_finish(void) { /* force close */ if (_refcnt > 0) { @@ -221,6 +238,11 @@ static void _vconf_finish(void) if (gsource_tbl) g_hash_table_remove_all(gsource_tbl); + + if (g_rec_mutex_trylock(&vconf_mutex)) + g_rec_mutex_unlock(&vconf_mutex); + + g_rec_mutex_clear(&vconf_mutex); } EXPORT char *vconf_keynode_get_name(keynode_t *keynode) @@ -383,10 +405,10 @@ static void _vconf_restore_connection(enum buxton_status status, return; /* LCOV_EXCL_START */ - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); if (!noti_tbl) { _refcnt = 0; - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return; } @@ -395,12 +417,12 @@ static void _vconf_restore_connection(enum buxton_status status, if (r != 0) { _refcnt = 0; LOGE("Can't connect to buxton: %d", buxton_err_get_errno()); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return; } g_hash_table_foreach(noti_tbl, (GHFunc)_vconf_restore_noti_cb, NULL); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); /* LCOV_EXCL_STOP */ } @@ -502,26 +524,26 @@ static gboolean _vconf_call_noti_cb(gpointer data) cb_info->source = NULL; - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); noti = g_hash_table_lookup(noti_tbl, node->keyname); if (!noti) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); g_hash_table_remove(gsource_tbl, GINT_TO_POINTER(cb_info->id)); return G_SOURCE_REMOVE; } if (!_vconf_find_noti_cb(noti, noticb->cb)) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); g_hash_table_remove(gsource_tbl, GINT_TO_POINTER(cb_info->id)); return G_SOURCE_REMOVE; } - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); noticb->cb(node, noticb->user_data); - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); g_hash_table_remove(gsource_tbl, GINT_TO_POINTER(cb_info->id)); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return G_SOURCE_REMOVE; } @@ -534,10 +556,10 @@ static void _vconf_notify_cb(const struct buxton_layer *layer, const char *key, struct noti* noti; GList *iter; - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); noti = g_hash_table_lookup(noti_tbl, key); if (!noti) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return; } @@ -551,14 +573,14 @@ static void _vconf_notify_cb(const struct buxton_layer *layer, const char *key, noticb = iter->data; cb_info = _vconf_create_callback_info(key, val, noticb); if (!cb_info) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return; } g_hash_table_insert(gsource_tbl, GINT_TO_POINTER(cb_info->id), cb_info); } - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); } static struct noti_cb *_vconf_find_noti_cb(struct noti *noti, vconf_callback_fn cb) @@ -682,10 +704,10 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb, return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -695,7 +717,7 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb, r = _vconf_create_noti(key, cb, user_data, ¬i); if (r != 0) { _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -715,7 +737,7 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb, } _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); if (r != 0) { VCONF_SET_ERRNO(r); @@ -755,10 +777,10 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -766,7 +788,7 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) noti = g_hash_table_lookup(noti_tbl, key); if (!noti) { _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(ENOENT); return -1; } @@ -774,7 +796,7 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) noticb = _vconf_find_noti_cb(noti, cb); if (!noticb || !noticb->active) { _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(ENOENT); return -1; } @@ -789,7 +811,7 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) if (cnt > 0) { _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return 0; } @@ -807,7 +829,7 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) /* decrease reference count */ _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return 0; } @@ -815,10 +837,10 @@ static int _vconf_set(const char *key, const struct buxton_value *val) { int r; - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return r; } @@ -829,7 +851,7 @@ static int _vconf_set(const char *key, const struct buxton_value *val) } _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return r; } @@ -955,10 +977,10 @@ static int _vconf_get(const char *key, enum buxton_key_type type, int r; struct buxton_value *v; - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return r; } @@ -984,7 +1006,7 @@ static int _vconf_get(const char *key, enum buxton_key_type type, } _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return r; } @@ -1536,10 +1558,10 @@ EXPORT int vconf_get(keylist_t *keylist, return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1549,7 +1571,7 @@ EXPORT int vconf_get(keylist_t *keylist, r = buxton_err_get_errno(); LOGE("get key list: errno %d", r); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1571,7 +1593,7 @@ EXPORT int vconf_get(keylist_t *keylist, buxton_free_keys(names); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return 0; } @@ -1629,10 +1651,10 @@ EXPORT int vconf_unset(const char *in_key) return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1640,7 +1662,7 @@ EXPORT int vconf_unset(const char *in_key) r = buxton_unset_value_sync(client, _vconf_get_layer(in_key), in_key); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); if (r != 0) { r = buxton_err_get_errno(); @@ -1678,10 +1700,10 @@ EXPORT int vconf_unset_recursive(const char *in_dir) return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1691,7 +1713,7 @@ EXPORT int vconf_unset_recursive(const char *in_dir) r = buxton_err_get_errno(); LOGE("get key list: errno %d", r); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1700,20 +1722,20 @@ EXPORT int vconf_unset_recursive(const char *in_dir) if (strncmp(in_dir, names[i], dirlen)) continue; - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); r = vconf_unset(names[i]); - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); if (r != 0) { buxton_free_keys(names); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); return -1; } } buxton_free_keys(names); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); /* LCOV_EXCL_STOP */ return 0; @@ -1730,10 +1752,10 @@ EXPORT int vconf_sync_key(const char *in_key) return -1; } - pthread_mutex_lock(&vconf_lock); + _vconf_mutex_lock(); r = _vconf_con_open(); if (r != 0) { - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); VCONF_SET_ERRNO(r); return -1; } @@ -1741,7 +1763,7 @@ EXPORT int vconf_sync_key(const char *in_key) r = buxton_get_value_sync(client, _vconf_get_layer(in_key), in_key, &v); _vconf_con_close(); - pthread_mutex_unlock(&vconf_lock); + _vconf_mutex_unlock(); if (r != 0) { r = buxton_err_get_errno(); |