Fix concurrency issue in handling references
authorJosé Bollo <jose.bollo@iot.bzh>
Wed, 7 Jun 2017 11:59:08 +0000 (13:59 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Wed, 7 Jun 2017 11:59:08 +0000 (13:59 +0200)
Change-Id: Iaae331fbdadb88f26057a64193a026950dcb56e4
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-session.c
src/afb-ws-json1.c
src/locale-root.c

index 523cbf0..536cdbc 100644 (file)
@@ -324,7 +324,7 @@ struct afb_session *afb_session_get (const char *uuid, int *created)
 struct afb_session *afb_session_addref(struct afb_session *session)
 {
        if (session != NULL)
-               session->refcount++;
+               __atomic_add_fetch(&session->refcount, 1, __ATOMIC_RELAXED);
        return session;
 }
 
@@ -332,11 +332,12 @@ void afb_session_unref(struct afb_session *session)
 {
        if (session != NULL) {
                assert(session->refcount != 0);
-               --session->refcount;
-               if (session->refcount == 0 && session->uuid[0] == 0) {
-                       destroy (session);
-                       pthread_mutex_destroy(&session->mutex);
-                       free(session);
+               if (!__atomic_sub_fetch(&session->refcount, 1, __ATOMIC_RELAXED)) {
+                       if (session->uuid[0] == 0) {
+                               destroy (session);
+                               pthread_mutex_destroy(&session->mutex);
+                               free(session);
+                       }
                }
        }
 }
index 45e1cdb..c796b17 100644 (file)
@@ -145,13 +145,13 @@ error:
 
 static struct afb_ws_json1 *aws_addref(struct afb_ws_json1 *ws)
 {
-       ws->refcount++;
+       __atomic_add_fetch(&ws->refcount, 1, __ATOMIC_RELAXED);
        return ws;
 }
 
 static void aws_unref(struct afb_ws_json1 *ws)
 {
-       if (--ws->refcount == 0) {
+       if (!__atomic_sub_fetch(&ws->refcount, 1, __ATOMIC_RELAXED)) {
                afb_evt_listener_unref(ws->listener);
                afb_wsj1_unref(ws->wsj1);
                if (ws->cleanup != NULL)
index ee88f3f..ece4456 100644 (file)
@@ -331,7 +331,7 @@ struct locale_root *locale_root_create_at(int dirfd, const char *path)
  */
 struct locale_root *locale_root_addref(struct locale_root *root)
 {
-       root->refcount++;
+       __atomic_add_fetch(&root->refcount, 1, __ATOMIC_RELAXED);
        return root;
 }
 
@@ -341,7 +341,7 @@ struct locale_root *locale_root_addref(struct locale_root *root)
  */
 static void internal_unref(struct locale_root *root)
 {
-       if (!--root->intcount) {
+       if (!__atomic_sub_fetch(&root->intcount, 1, __ATOMIC_RELAXED)) {
                clear_container(&root->container);
                close(root->rootfd);
                free(root);
@@ -356,7 +356,7 @@ void locale_root_unref(struct locale_root *root)
 {
        size_t i;
 
-       if (root != NULL && !--root->refcount) {
+       if (root && !__atomic_sub_fetch(&root->refcount, 1, __ATOMIC_RELAXED)) {
                /* clear circular references through searchs */
                for (i = 0 ; i < LRU_COUNT ; i++)
                        locale_search_unref(root->lru[i]);
@@ -420,7 +420,7 @@ static struct locale_search *create_search(struct locale_root *root, const char
                errno = ENOMEM;
        } else {
                /* init */
-               root->intcount++;
+               __atomic_add_fetch(&root->intcount, 1, __ATOMIC_RELAXED);
                search->root = root;
                search->head = NULL;
                search->refcount = 1;
@@ -541,7 +541,7 @@ struct locale_search *locale_root_search(struct locale_root *root, const char *d
  */
 struct locale_search *locale_search_addref(struct locale_search *search)
 {
-       search->refcount++;
+       __atomic_add_fetch(&search->refcount, 1, __ATOMIC_RELAXED);
        return search;
 }
 
@@ -552,7 +552,7 @@ void locale_search_unref(struct locale_search *search)
 {
        struct locale_search_node *it, *nx;
 
-       if (search && !--search->refcount) {
+       if (search && !__atomic_sub_fetch(&search->refcount, 1, __ATOMIC_RELAXED)) {
                it = search->head;
                while(it != NULL) {
                        nx = it->next;