From: Haffon <31226194+Haffon@users.noreply.github.com> Date: Thu, 7 Sep 2017 01:33:07 +0000 (+0800) Subject: Merge pull request #2 from json-c/master X-Git-Tag: json-c-0.13-20171207~53^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=86a3a6475fd42ef999a3c0e205e097c62f8a1e65;p=thirdparty%2Fjson-c.git Merge pull request #2 from json-c/master merge upstream --- 86a3a6475fd42ef999a3c0e205e097c62f8a1e65 diff --cc json_object.c index 3cecc43e,ec4e2b6e..5edcd7e8 --- a/json_object.c +++ b/json_object.c @@@ -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; }