summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2022-03-04 10:48:26 +0900
committerHwankyu Jhun <h.jhun@samsung.com>2022-03-04 10:58:09 +0900
commit7719266b0b54ff15f3cea514c86c4f1e8a09db32 (patch)
tree5b016291a909cffe1a232f5fa50ffb9ab302f313
parentb20fde67c2a272734dcfeb6486acefea89aca7ca (diff)
downloadbuxton2-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.c122
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, &noti);
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();