library: add client mutex lock for noti callbacks 59/65059/2
authorJiwoong Im <jiwoong.im@samsung.com>
Thu, 7 Apr 2016 05:53:13 +0000 (14:53 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Fri, 8 Apr 2016 03:15:39 +0000 (12:15 +0900)
Change-Id: I6c999b37bb84b7ef78dda8a27d8bdcc0fc9839a3
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
lib/buxton2.c

index 17bddee..c49b3b2 100644 (file)
@@ -89,6 +89,7 @@ struct buxton_client {
 
 static GList *clients; /* data: buxton_client */
 static pthread_mutex_t clients_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t noti_cbs_lock = PTHREAD_MUTEX_INITIALIZER;
 static guint32 client_msgid;
 
 static struct buxton_value *value_create(enum buxton_key_type type, void *value)
@@ -445,6 +446,7 @@ static int proc_msg_noti(struct buxton_client *client, uint8_t *data, int len)
                return -1;
        }
 
+       pthread_mutex_lock(&noti_cbs_lock);
        for (l = noti->callbacks; l; l = g_list_next(l)) {
                struct bxt_noti_cb *noticb = l->data;
 
@@ -452,9 +454,12 @@ static int proc_msg_noti(struct buxton_client *client, uint8_t *data, int len)
                        continue;
 
                assert(noticb->callback);
+               pthread_mutex_unlock(&noti_cbs_lock);
                noticb->callback(rqst.layer, rqst.key, rqst.val, noticb->data);
+               pthread_mutex_lock(&noti_cbs_lock);
        }
 
+       pthread_mutex_unlock(&noti_cbs_lock);
        free_request(&rqst);
 
        return 0;
@@ -505,12 +510,14 @@ static int add_noticb(struct bxt_noti *noti, buxton_notify_callback notify,
        assert(noti);
        assert(notify);
 
+       pthread_mutex_lock(&noti_cbs_lock);
        for (l = noti->callbacks; l; l = g_list_next(l)) {
                noticb = l->data;
 
                if (noticb->callback == notify) {
                        if (noticb->deleted == FALSE) {
                                errno = EEXIST;
+                               pthread_mutex_unlock(&noti_cbs_lock);
                                return -1;
                        }
 
@@ -518,13 +525,16 @@ static int add_noticb(struct bxt_noti *noti, buxton_notify_callback notify,
                        noticb->callback = notify;
                        noticb->data = notify_data;
 
+                       pthread_mutex_unlock(&noti_cbs_lock);
                        return 0;
                }
        }
 
        noticb = calloc(1, sizeof(*noticb));
-       if (!noticb)
+       if (!noticb) {
+               pthread_mutex_unlock(&noti_cbs_lock);
                return -1;
+       }
 
        noticb->deleted = FALSE;
        noticb->callback = notify;
@@ -532,6 +542,7 @@ static int add_noticb(struct bxt_noti *noti, buxton_notify_callback notify,
 
        noti->callbacks = g_list_append(noti->callbacks, noticb);
 
+       pthread_mutex_unlock(&noti_cbs_lock);
        return 0;
 }
 
@@ -1279,6 +1290,7 @@ static gboolean del_noticb_cb(gpointer data)
 
        assert(noti);
 
+       pthread_mutex_lock(&noti_cbs_lock);
        for (l = noti->callbacks, ll = g_list_next(l); l;
                        l = ll, ll = g_list_next(ll)) {
                noticb = l->data;
@@ -1289,6 +1301,7 @@ static gboolean del_noticb_cb(gpointer data)
                        free(noticb);
                }
        }
+       pthread_mutex_unlock(&noti_cbs_lock);
 
        noti->id = 0;
 
@@ -1307,6 +1320,8 @@ static int del_noticb(struct bxt_noti *noti, buxton_notify_callback notify,
 
        cnt = 0;
        f = FALSE;
+
+       pthread_mutex_lock(&noti_cbs_lock);
        for (l = noti->callbacks; l; l = g_list_next(l)) {
                struct bxt_noti_cb *noticb = l->data;
 
@@ -1320,6 +1335,7 @@ static int del_noticb(struct bxt_noti *noti, buxton_notify_callback notify,
                if (noticb->deleted == FALSE)
                        cnt++;
        }
+       pthread_mutex_unlock(&noti_cbs_lock);
 
        if (!f) {
                errno = ENOENT;
@@ -1977,7 +1993,9 @@ static void free_noti(struct bxt_noti *noti)
        if (!noti)
                return;
 
+       pthread_mutex_lock(&clients_lock);
        g_list_free_full(noti->callbacks, (GDestroyNotify)free);
+       pthread_mutex_unlock(&clients_lock);
 
        if (noti->id) {
                g_source_remove(noti->id);