diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-11-27 16:49:32 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-11-27 16:49:32 +0100 |
commit | 23ee243113ac47730c7ca900b35a1abbcb568743 (patch) | |
tree | 563c106de9f3f832614f446c6f37f6555d004e89 /json_object.c | |
parent | c97bbd37972bd6e0ec9163a15db30b0159261be1 (diff) | |
download | json-c-23ee243113ac47730c7ca900b35a1abbcb568743.tar.gz |
reference increment and decrement is now atomic (when using a GCC compatible compiler), which allows passing json objects between threads
Diffstat (limited to 'json_object.c')
-rw-r--r-- | json_object.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/json_object.c b/json_object.c index 9ac22a3..cad3137 100644 --- a/json_object.c +++ b/json_object.c @@ -160,25 +160,29 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len) extern struct json_object* json_object_get(struct json_object *jso) { - if (jso) - jso->_ref_count++; + if (!jso) return jso; +#if defined __GNUC__ + __sync_add_and_fetch(&jso->_ref_count, 1); +#else + ++jso->_ref_count; +#endif return jso; } int json_object_put(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 __GNUC__ + if (__sync_fetch_and_sub(&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; } |