]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Merge pull request #2 from json-c/master
authorHaffon <31226194+Haffon@users.noreply.github.com>
Thu, 7 Sep 2017 01:33:07 +0000 (09:33 +0800)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2017 01:33:07 +0000 (09:33 +0800)
merge upstream

1  2 
arraylist.c
json_object.c

diff --cc arraylist.c
Simple merge
diff --cc json_object.c
index 3cecc43ed29db54e227fe8e568d5cdeb57fa993c,ec4e2b6e2b48f8af41b1b8266f4fa9c1a7fff92a..5edcd7e88d682348dc61b808cb1868d27608cd3c
@@@ -161,27 -161,39 +161,39 @@@ static int json_escape_str(struct print
  
  /* reference counting */
  
 -extern struct json_object* json_object_get(struct json_object *jso)
 +extern struct json_object* json_object_retain(struct json_object *jso)
  {
-       if (jso)
-               jso->_ref_count++;
+       if (!jso) return jso;
+ #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
+       __sync_add_and_fetch(&jso->_ref_count, 1);
+ #else
+       ++jso->_ref_count;
+ #endif        
        return jso;
  }
  
 -int json_object_put(struct json_object *jso)
 +int json_object_release(struct json_object *jso)
  {
-       if(jso)
-       {
-               jso->_ref_count--;
-               if(!jso->_ref_count)
-               {
-                       if (jso->_user_delete)
-                               jso->_user_delete(jso, jso->_userdata);
-                       jso->_delete(jso);
-                       return 1;
-               }
-       }
-       return 0;
+       if(!jso) return 0;
+ #if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
+       /* Note: this only allow the refcount to remain correct
+        * when multiple threads are adjusting it.  It is still an error 
+        * for a thread to decrement the refcount if it doesn't "own" it,
+        * as that can result in the thread that loses the race to 0
+        * operating on an already-freed object.
+        */
+       if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0) return 0;
+ #else
+       if (--jso->_ref_count > 0) return 0;
+ #endif
+       if (jso->_user_delete)
+               jso->_user_delete(jso, jso->_userdata);
+       jso->_delete(jso);
+       return 1;
  }