summaryrefslogtreecommitdiff
path: root/json_object.c
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-11-27 16:49:32 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-11-27 16:49:32 +0100
commit23ee243113ac47730c7ca900b35a1abbcb568743 (patch)
tree563c106de9f3f832614f446c6f37f6555d004e89 /json_object.c
parentc97bbd37972bd6e0ec9163a15db30b0159261be1 (diff)
downloadjson-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.c32
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;
}