Browse Source

Explicitly check for GCC's atomic functions instead of depending on the __GNUC__ define.

Add a comment mentioning the limitation even though the _ref_count value is hanled atomically.
tags/json-c-0.13-20171207
Eric Haszlakiewicz 8 years ago
parent
commit
5b11e9adff
2 changed files with 32 additions and 2 deletions
  1. +24
    -0
      configure.ac
  2. +8
    -2
      json_object.c

+ 24
- 0
configure.ac View File

@@ -66,6 +66,30 @@ AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]])
AC_MSG_CHECKING(for GCC atomic builtins)
AC_LINK_IFELSE(
[
AC_LANG_SOURCE([[
int main() {
volatile unsigned int val = 1;
/* Note: __sync_val_compare_and_swap isn't checked here
* because it's protected by __GCC_HAVE_SYNC_COMPARE_AND_SWAP_<n>,
* which is automatically defined by gcc.
*/
__sync_add_and_fetch(&val, 1);
__sync_sub_and_fetch(&val, 1);
return 0;
}
]])
],
[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_ATOMIC_BUILTINS],[1],[Has atomic builtins])
],
[
AC_MSG_RESULT([no])
AC_MSG_WARN([json-c will be built without atomic refcounts because atomic builtins are missing])
])

case "${host_os}" in
linux*)


+ 8
- 2
json_object.c View File

@@ -165,7 +165,7 @@ extern struct json_object* json_object_get(struct json_object *jso)
{
if (!jso) return jso;

#if defined __GNUC__
#ifdef HAVE_ATOMIC_BUILTINS
__sync_add_and_fetch(&jso->_ref_count, 1);
#else
++jso->_ref_count;
@@ -178,7 +178,13 @@ int json_object_put(struct json_object *jso)
{
if(!jso) return 0;

#if defined __GNUC__
#ifdef HAVE_ATOMIC_BUILTINS
/* 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;


Loading…
Cancel
Save